Changeset 30575 in osm for applications


Ignore:
Timestamp:
2014-08-08T00:47:24+02:00 (10 years ago)
Author:
donvip
Message:

[josm_opendata] MIF:

  • correct handling of charsets
  • support of multi segments polylines
  • improve unit tests
Location:
applications/editors/josm/plugins/opendata
Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/AbstractMapInfoReader.java

    r30563 r30575  
    44import java.io.BufferedReader;
    55import java.io.File;
    6 import java.io.FileInputStream;
    7 import java.io.FileNotFoundException;
    86import java.io.IOException;
    97import java.io.InputStreamReader;
    108import java.nio.charset.Charset;
     9import java.nio.charset.IllegalCharsetNameException;
     10import java.nio.charset.UnsupportedCharsetException;
     11import java.nio.file.Files;
    1112import java.util.ArrayList;
    1213import java.util.List;
     
    4748        }
    4849       
    49         protected final BufferedReader getDataReader(File headerFile, String extension, Charset charset) throws FileNotFoundException {
     50        protected final BufferedReader getDataReader(File headerFile, String extension, Charset charset) throws IOException {
    5051                File dataFile = getDataFile(headerFile, extension);
    51                 return dataFile.exists() ? new BufferedReader(new InputStreamReader(new FileInputStream(dataFile), charset)) : null;
     52                return dataFile.exists() ? Files.newBufferedReader(dataFile.toPath(), charset) : null;
    5253        }
    5354
    54         protected Charset parseCharset(String[] words) {
     55        protected Charset parseCharset(String[] words) throws IllegalCharsetNameException, UnsupportedCharsetException {
    5556                return parseCharset(words, 1);
    5657        }
    5758
    58         protected Charset parseCharset(String[] words, int index) {
     59        protected Charset parseCharset(String[] words, int index) throws IllegalCharsetNameException, UnsupportedCharsetException {
    5960                words[index] = words[index].replace("\"", "");
    6061                if (words[index].equalsIgnoreCase(CHARSET_WINDOWS_LATIN)) {
  • applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/MifReader.java

    r30574 r30575  
    1212import java.io.InputStream;
    1313import java.io.InputStreamReader;
     14import java.io.Reader;
    1415import java.io.UnsupportedEncodingException;
    1516import java.nio.charset.Charset;
     
    3132import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
    3233import org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler;
     34import org.openstreetmap.josm.plugins.opendata.core.io.InputStreamReaderUnbuffered;
    3335import org.openstreetmap.josm.plugins.opendata.core.util.OdUtils;
    3436
     
    4850        READING_POINTS,
    4951        END_POLYGON,
    50         START_POLYLINE,
     52        START_POLYLINE_SEGMENT,
    5153        END_POLYLINE
    5254    }
    53 
     55   
     56    private File file;
     57    private InputStream stream;
     58    protected Charset charset;
    5459    protected BufferedReader midReader;
    5560
     
    8691    private int numpolygons = -1;
    8792    private int numpts = -1;
     93   
     94    // PLine clause
     95    private int numsections = -1;
    8896   
    8997    public static DataSet parseDataSet(InputStream in, File file,
     
    281289        int index = parseAffineUnits(words);
    282290       
    283         // FIXME: no idea what projection has to be used for real with "non-earth" mode...
    284         josmProj = Projections.getProjectionByCode("EPSG:4326"); // WGS 84
    285        
    286291        units = words[index+1];
    287292       
     
    317322        case "nonearth":
    318323            parseCoordSysSyntax2(words);
     324           
     325            // Syntax2 is not meant to be used for maps, and still... # 9592 happened
     326            // From MapInfo documentation:
     327            // http://testdrive.mapinfo.com/TDC/mxtreme4java.nsf/22fbc128f401ad818525666a00646bda/50100fdbe3e0a85085256a770053be1a/$FILE/coordsys.txt
     328            // Use syntax 1 (above) to explicitly define a coordinate system for an Earth map (a map having coordinates which are specified with respect to a
     329            // location on the surface of the Earth). The optional Projection parameters dictate what map projection, if any, should be used in conjunction with
     330            // the coordinate system. If the Projection clause is omitted, MapBasic uses a longitude, latitude coordinate system using the North American Datum of 1927 (NAD-27).
     331            // Use syntax 2 to explicitly define a non-Earth coordinate system, such as the coordinate system used in a floor plan or other CAD drawing.
     332           
     333            // FIXME: allow user to choose projection ?
     334            josmProj = new CustomProjection(null);
    319335            break;
    320336        case "layout":
    321337        case "table":
    322338        case "window":
    323             // TODO: support Layout, Table, Window clauses
    324             Main.warn("TODO: "+line);
     339            Main.error("Unsupported CoordSys clause: "+line);
    325340            break;
    326341        default:
    327             Main.warn("Line "+lineNum+". Invalid CoordSys clause: "+line);
     342            Main.error("Line "+lineNum+". Invalid CoordSys clause: "+line);
    328343        }
    329344    }
     
    358373    }
    359374   
    360     private void startPolyLine() throws IOException {
     375    private void startPolyLineSegment(boolean initial) throws IOException {
     376        Way previousPolyline = polyline;
    361377        polyline = new Way();
    362378        ds.addPrimitive(polyline);
    363         readAttributes(polyline);
     379        if (initial) {
     380            readAttributes(polyline);
     381        } else if (previousPolyline != null) {
     382            // Not sure about how to handle multiple segments. In doubt we create a new way with the same tags
     383            polyline.setKeys(previousPolyline.getKeys());
     384        }
    364385        state = State.READING_POINTS;
    365386    }
    366387   
    367388    private void parsePLine(String[] words) throws IOException {
     389        numsections = 1;
    368390        if (words.length <= 1 || "MULTIPLE".equalsIgnoreCase(words[1])) {
    369             // TODO: pline with multiple sections
    370391            numpts = -1;
    371             state = State.START_POLYLINE;
     392            state = State.START_POLYLINE_SEGMENT;
     393            if (words.length >= 3) {
     394                // pline with multiple sections
     395                numsections = Integer.parseInt(words[2]);
     396            }
    372397        } else {
    373398            numpts = Integer.parseInt(words[1]); // Not described in PDF but found in real files: PLINE XX, with XX = numpoints
    374             startPolyLine();
     399            startPolyLineSegment(true);
    375400        }
    376401    }
     
    414439    }
    415440
    416     private DataSet parse(InputStream in, File file, ProgressMonitor instance, Charset charset) throws IOException {
     441    private void initializeReaders(InputStream in, File f, Charset cs, int bufSize) throws IOException {
     442        stream = in;
     443        charset = cs;
     444        file = f;
     445        Reader isr;
     446        // Did you know ? new InputStreamReader(in, charset) has a non-configurable buffer of 8kb :(
     447        if (bufSize < 8192) {
     448            isr = new InputStreamReaderUnbuffered(in, charset);
     449        } else {
     450            isr = new InputStreamReader(in, charset);
     451        }
     452        headerReader = new BufferedReader(isr, bufSize);
     453        if (midReader != null) {
     454            midReader.close();
     455        }
     456        midReader = getDataReader(file, ".mid", charset);
     457    }
     458   
     459    private DataSet parse(InputStream in, File file, ProgressMonitor instance, Charset cs) throws IOException {
    417460        try {
    418             headerReader = new BufferedReader(new InputStreamReader(in, charset));
    419             midReader = getDataReader(file, ".mid", charset);
    420             parseHeader();
    421             if (midReader != null) {
    422                 midReader.close();
     461            try {
     462                // Read header byte per byte until we determine correct charset
     463                initializeReaders(in, file, cs, 1);
     464                parseHeader();
     465                return ds;
     466            } finally {
     467                if (midReader != null) {
     468                    midReader.close();
     469                }
    423470            }
    424             return ds;
    425471        } catch (UnsupportedEncodingException e) {
    426472            throw new IOException(e);
     
    433479            parseVersion(words);
    434480        } else if (words[0].equalsIgnoreCase("Charset")) {
    435             parseCharset(words);
     481            // Reinitialize readers with an efficient buffer value now we know for sure the good charset
     482            initializeReaders(stream, file, parseCharset(words), 8192);
    436483        } else if (words[0].equalsIgnoreCase("Delimiter")) {
    437484            parseDelimiter(words);
     
    460507                state = State.READING_POINTS;
    461508               
    462             } else if (state == State.START_POLYLINE) {
     509            } else if (state == State.START_POLYLINE_SEGMENT) {
    463510                numpts = Integer.parseInt(words[0]);
    464                 startPolyLine();
     511                startPolyLineSegment(polyline != null);
    465512               
    466513            } else if (state == State.READING_POINTS && numpts > 0) {
     
    485532                        }
    486533                    } else if (polyline != null) {
    487                         state = State.UNKNOWN;
    488                         polyline = null;
     534                        if (--numsections > 0) {
     535                            state = State.START_POLYLINE_SEGMENT;
     536                        } else {
     537                            state = State.UNKNOWN;
     538                            polyline = null;
     539                        }
    489540                    }
    490541                }
  • applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/TabReader.java

    r30563 r30575  
    88import java.io.InputStreamReader;
    99import java.nio.charset.Charset;
     10import java.nio.charset.IllegalCharsetNameException;
     11import java.nio.charset.UnsupportedCharsetException;
    1012import java.util.ArrayList;
    1113import java.util.List;
    1214
    13 import org.geotools.data.shapefile.files.TabFiles;
    1415import org.geotools.data.shapefile.dbf.DbaseFileReader;
    1516import org.geotools.data.shapefile.dbf.DbaseFileReader.Row;
     17import org.geotools.data.shapefile.files.TabFiles;
    1618import org.openstreetmap.josm.data.osm.DataSet;
    1719import org.openstreetmap.josm.gui.progress.ProgressMonitor;
     
    111113        }
    112114
    113         private void parseType(String[] words) {
     115        private void parseType(String[] words) throws IllegalCharsetNameException, UnsupportedCharsetException {
    114116                if (words[1].equalsIgnoreCase("NATIVE") && words[2].equalsIgnoreCase("Charset")) {
    115117                        datCharset = parseCharset(words, 3);
  • applications/editors/josm/plugins/opendata/test/unit/org/openstreetmap/josm/plugins/opendata/core/io/NonRegFunctionalTests.java

    r30573 r30575  
    1616
    1717import org.openstreetmap.josm.TestUtils;
     18import org.openstreetmap.josm.data.coor.LatLon;
    1819import org.openstreetmap.josm.data.osm.DataSet;
    1920import org.openstreetmap.josm.data.osm.Node;
     
    3233        Collection<Node> nodes = ds.getNodes();
    3334        assertFalse("No nodes in dataset for "+context, nodes.isEmpty());
    34         // Nodes should all have coordinates
     35        // Nodes should all have valid coordinates
    3536        for (Node n : nodes) {
    36             assertTrue("Node without coordinate found for "+context, n.getCoor() != null);
     37            LatLon latlon = n.getCoor();
     38            assertTrue("Node without coordinate found for "+context, latlon != null);
     39            assertTrue("Node with invalid coordinate ("+latlon+") found for "+context, latlon.isValid());
    3740        }
    3841        // and no empty ways
Note: See TracChangeset for help on using the changeset viewer.