All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opentripplanner.openstreetmap.BinaryOpenStreetMapProvider Maven / Gradle / Ivy

package org.opentripplanner.openstreetmap;

import org.openstreetmap.osmosis.osmbinary.file.BlockInputStream;
import org.opentripplanner.datastore.DataSource;
import org.opentripplanner.datastore.FileType;
import org.opentripplanner.datastore.file.FileDataSource;
import org.opentripplanner.graph_builder.module.osm.OSMDatabase;
import org.opentripplanner.util.ProgressTracker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;

/**
 * Parser for the OpenStreetMap PBF format. Parses files in three passes:
 * First the relations, then the ways, then the nodes are also loaded.
 */
public class BinaryOpenStreetMapProvider {
    private static final Logger LOG = LoggerFactory.getLogger(BinaryOpenStreetMapProvider.class);

    private final DataSource source;
    private final boolean cacheDataImMem;
    private byte[] cachedBytes = null;


    /** For tests */
    public BinaryOpenStreetMapProvider(File file, boolean cacheDataImMem) {
        this(new FileDataSource(file, FileType.OSM), cacheDataImMem);
    }

    public BinaryOpenStreetMapProvider(DataSource source, boolean cacheDataImMem) {
        this.source = source;
        this.cacheDataImMem = cacheDataImMem;
    }

    public void readOSM(OSMDatabase osmdb) {
        try {
            BinaryOpenStreetMapParser parser = new BinaryOpenStreetMapParser(osmdb);

            parsePhase(parser, OsmParserPhase.Relations);
            osmdb.doneFirstPhaseRelations();

            parsePhase(parser, OsmParserPhase.Ways);
            osmdb.doneSecondPhaseWays();

            parsePhase(parser, OsmParserPhase.Nodes);
            osmdb.doneThirdPhaseNodes();
        }
        catch (Exception ex) {
            throw new IllegalStateException("error loading OSM from path " + source.path(), ex);
        }
    }

    private void parsePhase(BinaryOpenStreetMapParser parser, OsmParserPhase phase) throws IOException {
        parser.setPhase(phase);
        BlockInputStream in = null;
        try {
            in = new BlockInputStream(createInputStream(phase), parser);
            in.process();
        }
        finally {
            // Close
            try { if(in != null) { in.close(); } }
            catch (Exception e) { LOG.error(e.getMessage(), e); }
        }
    }

    private InputStream createInputStream(OsmParserPhase phase) {
        if(cacheDataImMem) {
            if(cachedBytes == null) {
                cachedBytes = source.asBytes();
            }
            return track(phase, cachedBytes.length, new ByteArrayInputStream(cachedBytes));
        }
        return track(phase, source.size(), source.asInputStream());
    }

    @SuppressWarnings("Convert2MethodRef")
    private static InputStream track(OsmParserPhase phase, long size, InputStream inputStream) {
        // Keep logging lambda, replacing it with a method-ref will cause the
        // logging to report incorrect class and line number
        return ProgressTracker.track(
                "Parse OSM " + phase, 1000, size,
                inputStream,
                m -> LOG.info(m)
        );
    }

    public String toString() {
        return "BinaryFileBasedOpenStreetMapProviderImpl(" + source.path() + ")";
    }

    public void checkInputs() {
        if (!source.exists()) {
            throw new RuntimeException("Can't read OSM path: " + source.path());
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy