Changeset 16933 in josm for trunk/src/org


Ignore:
Timestamp:
2020-08-26T20:24:32+02:00 (4 years ago)
Author:
simon04
Message:

fix #19624 - Support reading line-delimited GeoJSON (RFC 7464; patch by taylor.smock)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/io/GeoJSONReader.java

    r16311 r16933  
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
     6import java.io.BufferedInputStream;
     7import java.io.BufferedReader;
     8import java.io.ByteArrayInputStream;
     9import java.io.IOException;
    610import java.io.InputStream;
     11import java.io.InputStreamReader;
     12import java.nio.charset.StandardCharsets;
    713import java.util.List;
    814import java.util.Map;
     
    5258    private static final String GEOMETRY = "geometry";
    5359    private static final String TYPE = "type";
     60    /** The record separator is 0x1E per RFC 7464 */
     61    private static final byte RECORD_SEPARATOR_BYTE = 0x1E;
    5462    private JsonParser parser;
    5563    private Projection projection = Projections.getProjectionByCode("EPSG:4326"); // WGS 84
     
    351359    }
    352360
     361    /**
     362     * Check if the inputstream follows RFC 7464
     363     * @param source The source to check (should be at the beginning)
     364     * @return {@code true} if the initial character is {@link GeoJSONReader#RECORD_SEPARATOR_BYTE}.
     365     */
     366    private static boolean isLineDelimited(InputStream source) {
     367        source.mark(2);
     368        try {
     369            int start = source.read();
     370            if (RECORD_SEPARATOR_BYTE == start) {
     371                return true;
     372            }
     373            source.reset();
     374        } catch (IOException e) {
     375            Logging.error(e);
     376        }
     377        return false;
     378    }
     379
    353380    @Override
    354381    protected DataSet doParseDataSet(InputStream source, ProgressMonitor progressMonitor) throws IllegalDataException {
    355         setParser(Json.createParser(source));
     382        InputStream markSupported = source.markSupported() ? source : new BufferedInputStream(source);
    356383        ds.setUploadPolicy(UploadPolicy.DISCOURAGED);
    357         try {
    358             parse();
    359         } catch (JsonParsingException e) {
    360             throw new IllegalDataException(e);
     384        if (isLineDelimited(markSupported)) {
     385            BufferedReader reader = new BufferedReader(new InputStreamReader(markSupported));
     386            String line = null;
     387            String rs = new String(new byte[]{RECORD_SEPARATOR_BYTE}, StandardCharsets.US_ASCII);
     388            try {
     389                while ((line = reader.readLine()) != null) {
     390                    line = line.replaceFirst(rs, "");
     391                    try (InputStream is = new ByteArrayInputStream(line.getBytes())) {
     392                        setParser(Json.createParser(is));
     393                        parse();
     394                    } catch (JsonParsingException e) {
     395                        throw new IllegalDataException(e);
     396                    } finally {
     397                        parser.close();
     398                    }
     399                }
     400            } catch (IOException e) {
     401                throw new IllegalDataException(e);
     402            }
     403        } else {
     404            setParser(Json.createParser(markSupported));
     405            try {
     406                parse();
     407            } catch (JsonParsingException e) {
     408                throw new IllegalDataException(e);
     409            }
    361410        }
    362411        return getDataSet();
Note: See TracChangeset for help on using the changeset viewer.