/*
This file is part of RouteConverter.
RouteConverter is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
RouteConverter is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with RouteConverter; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Copyright (C) 2007 Christian Pesch. All Rights Reserved.
*/
package slash.navigation.graphhopper;
import org.openstreetmap.osmosis.osmbinary.Fileformat;
import org.openstreetmap.osmosis.osmbinary.Osmformat;
import slash.navigation.common.BoundingBox;
import slash.navigation.common.SimpleNavigationPosition;
import java.io.*;
import java.util.logging.Logger;
import java.util.zip.InflaterInputStream;
import static java.lang.String.format;
/**
* Provides PBF functionality.
*
* @author Christian Pesch
*/
public class PbfUtil {
private static final Logger log = Logger.getLogger(PbfUtil.class.getName());
private static final String OSM_HEADER = "OSMHeader";
public static final String DOT_OSM = ".osm";
public static final String DOT_PBF = ".pbf";
private static final double LONGITUDE_LATITUDE_RESOLUTION = 1000.0 * 1000.0 * 1000.0;
public static BoundingBox extractBoundingBox(File file) throws IOException {
try (InputStream inputStream = new FileInputStream(file)) {
return extractBoundingBox(inputStream);
}
}
public static BoundingBox extractBoundingBox(InputStream inputStream) {
try {
DataInputStream dataInputStream = new DataInputStream(inputStream);
boolean foundOsmHeader = false;
while (!foundOsmHeader) {
if (dataInputStream.available() <= 0)
break;
byte[] blobHeaderBytes = new byte[dataInputStream.readInt()];
int readBlobHeader = dataInputStream.read(blobHeaderBytes);
if (readBlobHeader != blobHeaderBytes.length) {
log.warning(format("Wanted to read %d blob header bytes, but got only %d bytes", blobHeaderBytes.length, readBlobHeader));
return null;
}
Fileformat.BlobHeader blobHeader = Fileformat.BlobHeader.parseFrom(blobHeaderBytes);
byte[] blobBytes = new byte[blobHeader.getDatasize()];
int readBlob = dataInputStream.read(blobBytes);
if (readBlob != blobBytes.length) {
log.warning(format("Wanted to read %d blob bytes, but got only %d bytes", blobBytes.length, readBlob));
return null;
}
Fileformat.Blob blob = Fileformat.Blob.parseFrom(blobBytes);
InputStream blobData;
if (blob.hasZlibData()) {
blobData = new InflaterInputStream(blob.getZlibData().newInput());
} else {
blobData = blob.getRaw().newInput();
}
if (blobHeader.getType().equals(OSM_HEADER)) {
Osmformat.HeaderBlock headerBlock = Osmformat.HeaderBlock.parseFrom(blobData);
if (headerBlock.hasBbox())
return toBoundingBox(headerBlock.getBbox());
foundOsmHeader = true;
} else
log.info("Skipped block " + blobHeader.getType() + " with " + blobBytes.length + " bytes");
}
} catch (IOException e) {
log.warning(format("Could not extract pbf bounding box: %s", e));
}
return null;
}
private static BoundingBox toBoundingBox(Osmformat.HeaderBBox bbox) {
return new BoundingBox(new SimpleNavigationPosition(asCoordinate(bbox.getRight()), asCoordinate(bbox.getTop())),
new SimpleNavigationPosition(asCoordinate(bbox.getLeft()), asCoordinate(bbox.getBottom())));
}
private static double asCoordinate(long coordinate) {
return coordinate / LONGITUDE_LATITUDE_RESOLUTION;
}
}