comparison flys-backend/src/main/java/de/intevation/flys/importer/parsers/DA66Parser.java @ 4712:70842db72ee4

Include improved DA66Parser into importer.
author Felix Wolfsteller <felix.wolfsteller@intevation.de>
date Wed, 19 Dec 2012 14:04:12 +0100
parents aa718770308e
children 2f7a509f5acf
comparison
equal deleted inserted replaced
4711:35dd03e04e38 4712:70842db72ee4
26 public class DA66Parser extends LineParser 26 public class DA66Parser extends LineParser
27 { 27 {
28 /** Private logger. */ 28 /** Private logger. */
29 private static Logger logger = Logger.getLogger(DA66Parser.class); 29 private static Logger logger = Logger.getLogger(DA66Parser.class);
30 30
31 // TODO: Most of the Point/y/z group matches are optional! 31 private static String HEAD_HEAD = "00";
32 public static final Pattern LINE_PATTERN = 32 private static String HEAD_GEOM = "66"; // "Values"
33 Pattern.compile("^([0-9 -]{2})" + // Type 33 private static String HEAD_ENDG = "88"; // Probably never used.
34
35 private static final Pattern LINE_PATTERN =
36 Pattern.compile("^([0-9 -]{2})" + // Type (00|66|88)
34 "([0-9 -]{5})" + // unset 37 "([0-9 -]{5})" + // unset
35 "([0-9 -]{2})" + // id 38 "([0-9 -]{2})" + // id
36 "([0-9 -]{9})" + // station 39 "([0-9 -]{9})" + // station
37 "([0-9 -]{2})" + // running number 40 "([0-9 -]{2})" + // running number
38 "([0-9 -]{1})" + // point id 41 "([0-9 -]{1})?" + // point id
39 /* 42 /*
40 Would be great if we could express the pattern as this: 43 Would be great if we could express the pattern as this:
41 ([0-9 -]{1})([0-9 -JKMLMNOPQR]{7})([0-9 -]{7})+ 44 ([0-9 -]{1})([0-9 -JKMLMNOPQR]{7})([0-9 -]{7})+
42 */ 45 */
43 "([0-9 -JKMLMNOPQR]{7})" + // y 46 "([0-9 -JKMLMNOPQR]{7})?" + // y
44 "([0-9 -]{7})" + // z 47 "([0-9 -]{7})?" + // z
45 "([0-9 -]{1})" + // point id 48 "([0-9 -]{1})?" + // point id
46 "([0-9 -JKMLMNOPQR]{7})" + // y 49 "([0-9 -JKMLMNOPQR]{7})?" + // y
47 "([0-9 -]{7})" + // z 50 "([0-9 -]{7})?" + // z
48 "([0-9 -]{1})" + // point id 51 "([0-9 -]{1})?" + // point id
49 "([0-9 -JKMLMNOPQR]{7})" + // y 52 "([0-9 -JKMLMNOPQR]{7})?" + // y
50 "([0-9 -]{7})" + // z 53 "([0-9 -]{7})?" + // z
51 "([0-9 -]{1})" + // point id 54 "([0-9 -]{1})?" + // point id
52 "([0-9 -JKMLMNOPQR]{7})" + // y 55 "([0-9 -JKMLMNOPQR]{7})?" + // y
53 "([0-9 -]{7})" // z 56 "([0-9 -]{7})?" // z
54 ); 57 );
55 //Pattern.compile("^([0-9 -]{2})"); 58 //Pattern.compile("^([0-9 -]{2})");
56 59
60 /** Indices to match group of main regex. */
61 private static enum FIELD {
62 HEAD ( 1),
63 UNSET ( 2),
64 ID ( 3),
65 STATION ( 4),
66 RUNNR ( 5),
67 POINT_1_ID( 6),
68 POINT_1_Y ( 7),
69 POINT_1_Z ( 8),
70 POINT_2_ID( 9),
71 POINT_2_Y (10),
72 POINT_2_Z (11),
73 POINT_3_ID(12),
74 POINT_3_Y (13),
75 POINT_3_Z (14),
76 POINT_4_ID(15),
77 POINT_4_Y (16),
78 POINT_4_Z (17);
79
80 private int idx;
81 FIELD(int idx) {
82 this.idx = idx;
83 }
84 int getIdx() {
85 return idx;
86 }
87 }
88
89 /** Header lines of da66 can define a type. */
57 private static enum Type { 90 private static enum Type {
58 DATE ( 0), 91 DATE ( 0),
59 HEKTOSTONE_LEFT ( 1), //grm. "Standlinie" 92 HEKTOSTONE_LEFT ( 1), //grm. "Standlinie"
60 HEKTOSTONE_RIGHT ( 2), 93 HEKTOSTONE_RIGHT ( 2),
61 CHANNEL_LEFT ( 3), //grm. "Fahrrinne" 94 CHANNEL_LEFT ( 3), //grm. "Fahrrinne"
115 static { 148 static {
116 typeMap = new HashMap<Integer, Type>(); 149 typeMap = new HashMap<Integer, Type>();
117 for (Type t: Type.values()) { 150 for (Type t: Type.values()) {
118 typeMap.put(new Integer(t.getId()), t); 151 typeMap.put(new Integer(t.getId()), t);
119 } 152 }
153 // TODO populate and respect header type.
120 implementedTypes = new ArrayList<Type>(); 154 implementedTypes = new ArrayList<Type>();
121 //implementedTypes.add(..); 155 //implementedTypes.add(..);
122 } 156 }
123 157
158
159 /** The current line to which add points. */
160 private List<XY> currentLine;
161
162
163 // TODO refactor, its shared with PRFParser.
124 public interface Callback { 164 public interface Callback {
125 boolean da60Accept(File file); 165 boolean da66Accept(File file);
126 void da60Parsed(DA66Parser parser); 166 void da66Parsed(DA66Parser parser);
127 } // interface Parser 167 } // interface Parser
128 168
169
170 /** Data collected so far, last element will be currentLine. */
129 protected Map<Double, List<XY>> data; 171 protected Map<Double, List<XY>> data;
130 172
131 173
132 public DA66Parser() { 174 public DA66Parser() {
133 data = new TreeMap<Double, List<XY>>(); 175 data = new TreeMap<Double, List<XY>>();
146 return index == -1 188 return index == -1
147 ? name 189 ? name
148 : name.substring(0, index); 190 : name.substring(0, index);
149 } 191 }
150 192
151 public void reset() {
152 data.clear();
153 }
154
155 public void parseDA66s(File root, final Callback callback) { 193 public void parseDA66s(File root, final Callback callback) {
156 194
195 // TODO use the removeExtension/guess description and date.
157 FileTools.walkTree(root, new FileTools.FileVisitor() { 196 FileTools.walkTree(root, new FileTools.FileVisitor() {
158 @Override 197 @Override
159 public boolean visit(File file) { 198 public boolean visit(File file) {
160 if (file.isFile() && file.canRead() 199 if (file.isFile() && file.canRead()
161 && file.getName().toLowerCase().endsWith(".d66") 200 && file.getName().toLowerCase().endsWith(".d66")
162 && (callback == null || callback.da60Accept(file))) { 201 && (callback == null || callback.da66Accept(file))) {
163 reset(); 202 reset();
164 try { 203 try {
165 parse(file); 204 parse(file);
166 logger.info("parsing done"); 205 logger.info("parsing done");
167 if (callback != null) { 206 if (callback != null) {
168 callback.da60Parsed(DA66Parser.this); 207 callback.da66Parsed(DA66Parser.this);
169 } 208 }
170 } 209 }
171 catch (IOException ioe) { 210 catch (IOException ioe) {
172 logger.error("IOException while parsing file"); 211 logger.error("IOException while parsing file");
173 return false; 212 return false;
176 return true; 215 return true;
177 } 216 }
178 }); 217 });
179 } 218 }
180 219
181 // LineParser 220
182 @Override 221 /**
183 protected void finish() {} 222 * Get the Index of the last cross-section lines point.
184 223 * @return last points index, -1 if not available.
185 /** Called for each line. Try to extract info from a da66 line. */ 224 */
225 private int lastPointIdx() {
226 if (currentLine == null || currentLine.isEmpty()) {
227 return -1;
228 }
229 XY lastPoint = this.currentLine.get(currentLine.size()-1);
230 return lastPoint.getIndex();
231 }
232
233
234 /**
235 * Add a Point (YZ,Index) to the current cross section line.
236 * @param y The y coordinate of new point.
237 * @param z The z coordinate of new point.
238 * @param idx Ignored, the parameter of new point.
239 * @return true if point could been added, false otherwise (e.g. not
240 * parsable y or z values.
241 */
242 private boolean addPoint(String y, String z, String idx) {
243 if (z == null || y == null || idx == null) {
244 logger.error("Incomplete point definition");
245 return false;
246 }
247
248 Double iy;
249 Double iz;
250 try {
251 iy = Double.parseDouble(y);
252 iz = Double.parseDouble(z);
253 }
254 catch(java.lang.NumberFormatException nfe) {
255 logger.error("Could not parse Number: " + nfe.getMessage());
256 return false;
257 }
258
259 // We ignore idx, and increment instead.
260 Integer index;
261 int lastPointIdx = lastPointIdx();
262 if (lastPointIdx <= 0) {
263 index = 1;
264 } else {
265 index = lastPointIdx + 1;
266 }
267
268 currentLine.add(new XY(iy, iz, index));
269 return true;
270 }
271
272
273 /** Called before consuming first line of file. */
274 public void reset() {
275 data.clear();
276 currentLine = new ArrayList<XY>();
277 }
278
279
280 /**
281 * Called for each line. Try to extract info from a da66 line.
282 */
186 @Override 283 @Override
187 protected void handleLine(int lineNum, String line) { 284 protected void handleLine(int lineNum, String line) {
188 if (line.substring(0,2).equals("00")) { 285 String head = line.substring(0,2);
189 logger.warn("Hit a 00"); 286 if (HEAD_HEAD.equals(head)) {
190 } 287 logger.debug("Hit a 00");
191 else if (line.substring(0,2).equals("66")) { 288 Matcher m = LINE_PATTERN.matcher(line);
192 String station = line.substring(10,18); 289 if (m.find()) {
193 logger.info(station); 290 // Actually matches!
291 currentLine = new ArrayList<XY>();
292 data.put(Double.parseDouble(m.group(FIELD.STATION.getIdx())),
293 currentLine);
294 }
295 else {
296 logger.error("HEAD line bad.");
297 }
298 }
299 else if (HEAD_GEOM.equals(head)) {
194 Matcher m = LINE_PATTERN.matcher(line); 300 Matcher m = LINE_PATTERN.matcher(line);
195 if(m.find()) 301 if (m.find()) {
196 logger.warn("Group1: " + m.group(1)); 302 //logger.info("Station: " + m.group(FIELD.STATION.getIdx()));
197 else 303 // TODO if last station differs, error and abort
198 logger.warn("no match in " + line); 304 if (m.group(FIELD.POINT_1_ID.getIdx()) != null) {
199 //logger.warn("Hit a 66"); 305 // Point 1
200 } 306 if(addPoint(
201 else if (line.substring(0,2).equals("88")) 307 m.group(FIELD.POINT_1_Y.getIdx()),
202 logger.warn("Hit a 88"); 308 m.group(FIELD.POINT_1_Z.getIdx()),
203 else 309 m.group(FIELD.POINT_1_ID.getIdx()))) {
204 logger.error("Do not know how to treat da66 line."); 310 // Point added.
311 }
312 else {
313 // Problematic point.
314 logger.error("A point could not be added");
315 }
316 }
317 if (m.group(FIELD.POINT_2_ID.getIdx()) != null) {
318 // Point 2
319 if(addPoint(
320 m.group(FIELD.POINT_2_Y.getIdx()),
321 m.group(FIELD.POINT_2_Z.getIdx()),
322 m.group(FIELD.POINT_2_ID.getIdx()))) {
323 // Point added.
324 }
325 else {
326 // Problematic point.
327 logger.error("A point could not be added");
328 }
329 }
330 if (m.group(FIELD.POINT_3_ID.getIdx()) != null) {
331 // Point 3
332 if(addPoint(
333 m.group(FIELD.POINT_3_Y.getIdx()),
334 m.group(FIELD.POINT_3_Z.getIdx()),
335 m.group(FIELD.POINT_3_ID.getIdx()))) {
336 // Point added.
337 }
338 else {
339 // Problematic point.
340 logger.error("A point could not be added");
341 }
342 }
343 if (m.group(FIELD.POINT_4_ID.getIdx()) != null) {
344 // Point 4
345 if(addPoint(
346 m.group(FIELD.POINT_4_Y.getIdx()),
347 m.group(FIELD.POINT_4_Z.getIdx()),
348 m.group(FIELD.POINT_4_ID.getIdx()))) {
349 // Point added.
350 }
351 else {
352 // Problematic point.
353 logger.error("A point could not be added");
354 }
355 }
356 }
357 else {
358 logger.warn("Line could not be parsed: ");
359 logger.warn(line);
360 }
361 }
362 else if (HEAD_GEOM.equals(head)) {
363 logger.debug("Hit a 88");
364 }
365 else {
366 logger.error("Do not know how to treat da66 line:");
367 logger.error(line);
368 }
369 }
370
371
372 /** Called when file is fully consumed. */
373 @Override
374 protected void finish() {
375 logger.info("Parsed " + data.size() + " lines");
205 } 376 }
206 377
207 378
208 /** Parses files given as arguments. */ 379 /** Parses files given as arguments. */
209 public static void main(String [] args) { 380 public static void main(String [] args) {
213 logger.warn("Start Parsing files."); 384 logger.warn("Start Parsing files.");
214 for (String arg: args) { 385 for (String arg: args) {
215 parser.parseDA66s(new File(arg), null); 386 parser.parseDA66s(new File(arg), null);
216 logger.warn("Parsing a file."); 387 logger.warn("Parsing a file.");
217 } 388 }
218 logger.error("Stopped Parsing files."); 389 logger.error("Finished Parsing files.");
219 } 390 }
220 } 391 }
221 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : 392 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org