// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.plugins.opendata.core.io.geographic; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.Charset; import java.nio.charset.IllegalCharsetNameException; import java.nio.charset.UnsupportedCharsetException; import java.util.ArrayList; import java.util.List; import org.geotools.data.shapefile.dbf.DbaseFileReader; import org.geotools.data.shapefile.dbf.DbaseFileReader.Row; import org.geotools.data.shapefile.files.TabFiles; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.data.osm.DataSet; import org.openstreetmap.josm.gui.progress.ProgressMonitor; import org.openstreetmap.josm.plugins.opendata.core.OdConstants; import org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler; import org.openstreetmap.josm.plugins.opendata.core.io.tabular.SpreadSheetHandler; import org.openstreetmap.josm.plugins.opendata.core.io.tabular.SpreadSheetReader; /** * MapInfo TAB reader * */ public class TabReader extends AbstractMapInfoReader { private Charset datCharset; private final AbstractDataSetHandler handler; public TabReader(AbstractDataSetHandler handler) { this.handler = handler; } public static DataSet parseDataSet(InputStream in, File file, AbstractDataSetHandler handler, ProgressMonitor instance) throws IOException { return new TabReader(handler).parse(in, file, instance, Charset.forName(OdConstants.ISO8859_15)); } private class TabOsmReader extends SpreadSheetReader { private final DbaseFileReader dbfReader; TabOsmReader(SpreadSheetHandler handler, TabFiles tabFiles) throws IOException { super(handler); this.dbfReader = new DbaseFileReader(tabFiles, false, datCharset, null); } @Override protected void initResources(InputStream in, ProgressMonitor progressMonitor) throws IOException { } @Override protected String[] readLine(ProgressMonitor progressMonitor) throws IOException { if (!dbfReader.hasNext()) { return null; } List<String> result = new ArrayList<>(); Row row = dbfReader.readRow(); for (int i = 0; i < columns.size(); i++) { Object o = row.read(i); if (o != null) { result.add(o.toString()); } else { result.add(""); } } return result.toArray(new String[0]); } } private DataSet parse(InputStream in, File file, ProgressMonitor instance, Charset charset) throws IOException { headerReader = new BufferedReader(new InputStreamReader(in, charset)); parseHeader(); try { File dataFile = getDataFile(file, ".dat"); ds = new TabOsmReader(handler != null ? handler.getSpreadSheetHandler() : null, new TabFiles(file, dataFile)). doParse(columns.toArray(new String[0]), instance); } catch (IOException e) { Main.error(e.getMessage()); } return ds; } @Override protected void parseHeaderLine(String[] words) throws IOException { if (words[0].equalsIgnoreCase("!table")) { // Do nothing } else if (words[0].equalsIgnoreCase("!version")) { parseVersion(words); } else if (words[0].equalsIgnoreCase("!charset")) { parseCharset(words); } else if (numcolumns > 0) { parseField(words); } else if (words[0].equalsIgnoreCase("Definition")) { // Do nothing } else if (words[0].equalsIgnoreCase("Type")) { parseType(words); } else if (words[0].equalsIgnoreCase("Fields")) { parseColumns(words); } else if (!line.isEmpty()) { Main.warn("Line "+lineNum+". Unknown clause in header: "+line); } } private void parseField(String[] words) { columns.add(words[0]); --numcolumns; } private void parseType(String[] words) throws IllegalCharsetNameException, UnsupportedCharsetException { if (words[1].equalsIgnoreCase("NATIVE") && words[2].equalsIgnoreCase("Charset")) { datCharset = parseCharset(words, 3); } else { Main.warn("Line "+lineNum+". Unknown Type clause in header: "+line); } } }