/* * MapMakerImporter.java * * Created on February 15, 2006, 1:34 PM * */ package ika.geoimport; import ika.geo.*; import ika.geoimport.*; import ika.gui.ProgressIndicator; import java.util.*; import java.io.*; /** * An importer for the MapMaker file format. * @author jenny */ public class MapMakerImporter extends GeoImporter { private String SEPARATOR = "\t"; private boolean readPoints = false; private long charsRead; public MapMakerImporter(){ } private String readDataLine(BufferedReader in) { try { while (true) { String str = in.readLine(); if (str == null) return null; this.charsRead += str.length() + 1; // '!' seem to mark comments if (str.startsWith("!")) continue; // if the first column is empty, the line is a comment if (str.startsWith(SEPARATOR)) continue; // every line must start with a number, otherwise it's a comment str = str.trim(); if (!str.matches("^\\d.*")) continue; return str; } } catch (java.io.IOException exc) { return null; } } private void readXY (float[] xy, BufferedReader in) { String str = readDataLine(in); StringTokenizer tokenizer = new StringTokenizer(str, SEPARATOR); xy[0] = Float.parseFloat((String)tokenizer.nextToken()); xy[1] = Float.parseFloat((String)tokenizer.nextToken()); } protected GeoObject importData(java.net.URL url) throws IOException { GeoSet geoSet = this.createGeoSet(); geoSet.setName(ika.utils.FileUtils.getFileNameWithoutExtension(url.getPath())); // count the numbers of read characters and get the size of the file // for progress indication this.charsRead = 0; long fileSize = url.openConnection().getContentLength(); BufferedReader in = new BufferedReader(new InputStreamReader (url.openStream())); try { String str; float[] xy = new float[2]; while ((str = this.readDataLine(in)) != null) { // don't use empty space ' ' to tokenize, since names can consist // of multiple words. StringTokenizer tokenizer = new StringTokenizer(str, SEPARATOR); int id = Integer.parseInt((String)tokenizer.nextToken()); String name = (String)tokenizer.nextToken(); int npts = Integer.parseInt((String)tokenizer.nextToken()); if (npts == 1 && this.readPoints) { // point this.readXY(xy, in); GeoPoint geoPoint = new GeoPoint(xy[0], xy[1]); geoPoint.setName(name); geoPoint.setID(id); geoSet.add(geoPoint); } else if (!this.readPoints) { // surface or line GeoPath geoPath = this.createGeoPath(); geoPath.setName(name); geoPath.setID(id); final boolean close = npts > 1; npts = Math.abs(npts); float startX = 0; float startY = 0; for (int i = 0; i < npts; i++) { this.readXY(xy, in); if (i == 0) { geoPath.moveTo(xy[0], xy[1]); startX = xy[0]; startY = xy[1]; } else { if (xy[0] == startX && xy[1] == startY) { geoPath.closePath(); if (i == npts - 1) break; this.readXY(xy, in); geoPath.moveTo(xy[0], xy[1]); startX = xy[0]; startY = xy[1]; i++; } else { geoPath.lineTo(xy[0], xy[1]); } } } if (geoPath.hasOneOrMorePoints()) { if (close) geoPath.closePath(); geoSet.add(geoPath); } } // update progress indicator ProgressIndicator progressIndicator = this.getProgressIndicator(); if (progressIndicator != null) { final int percentage = (int)(100d * this.charsRead / fileSize); progressIndicator.progress(percentage); if (progressIndicator.isAborted()) return null; } } } catch (NoSuchElementException e) { } finally { in.close(); } // assign VectorSymbol to GeoSet VectorSymbol symbol = new VectorSymbol(java.awt.Color.black, java.awt.Color.black, 1); symbol.setScaleInvariant(true); geoSet.setVectorSymbol(symbol); return geoSet; } public String getImporterName() { return "MapMaker Importer"; } public void setReadPoints(boolean readPoints) { this.readPoints = readPoints; } /** * Test if the passed file contains valid data. * At least one valid number is required. */ protected java.net.URL findDataURL(java.net.URL url) { if (url == null) return null; BufferedReader in = null; try { in = new BufferedReader(new InputStreamReader (url.openStream())); String str = this.readDataLine(in); StringTokenizer tokenizer = new StringTokenizer(str, SEPARATOR); Float.parseFloat((String)tokenizer.nextToken()); return url; } catch (Exception e) { return null; } finally { if (in != null) try { in.close(); } catch (IOException e) {} } } }