package btools.mapcreator; import java.io.*; import java.util.*; import java.util.zip.*; import btools.util.*; import org.openstreetmap.osmosis.osmbinary.Fileformat; /** * Parser for OSM data * * @author ab */ public class OsmParser extends MapCreatorBase { private BufferedReader _br; private NodeListener nListener; private WayListener wListener; private RelationListener rListener; public void readMap(File mapFile, NodeListener nListener, WayListener wListener, RelationListener rListener) throws Exception { this.nListener = nListener; this.wListener = wListener; this.rListener = rListener; System.out.println("*** PBF Parsing: " + mapFile); // once more for testing int rawBlobCount = 0; long bytesRead = 0L; // wait for file to become available while (!mapFile.exists()) { System.out.println("--- waiting for " + mapFile + " to become available"); Thread.sleep(10000); } long currentSize = mapFile.length(); long currentSizeTime = System.currentTimeMillis(); DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(mapFile))); for (; ; ) { // continue reading if either more then a 100 MB unread, or the current-size is known for more then 2 Minutes while (currentSize - bytesRead < 100000000L) { long newSize = mapFile.length(); if (newSize != currentSize) { currentSize = newSize; currentSizeTime = System.currentTimeMillis(); } else if (System.currentTimeMillis() - currentSizeTime > 120000) { break; } if (currentSize - bytesRead < 100000000L) { System.out.println("--- waiting for more data, currentSize=" + currentSize + " bytesRead=" + bytesRead); Thread.sleep(10000); } } int headerLength; try { headerLength = dis.readInt(); bytesRead += 4; } catch (EOFException e) { break; } byte[] headerBuffer = new byte[headerLength]; dis.readFully(headerBuffer); bytesRead += headerLength; Fileformat.BlobHeader blobHeader = Fileformat.BlobHeader.parseFrom(headerBuffer); byte[] blobData = new byte[blobHeader.getDatasize()]; dis.readFully(blobData); bytesRead += blobData.length; new BPbfBlobDecoder(blobHeader.getType(), blobData, this).process(); rawBlobCount++; } dis.close(); System.out.println("read raw blobs: " + rawBlobCount); } public void addNode(long nid, Map tags, double lat, double lon) { NodeData n = new NodeData(nid, lon, lat); n.setTags(tags); try { nListener.nextNode(n); } catch (Exception e) { throw new RuntimeException("error writing node: " + e); } } public void addWay(long wid, Map tags, LongList nodes) { WayData w = new WayData(wid, nodes); w.setTags((HashMap) tags); try { wListener.nextWay(w); } catch (Exception e) { throw new RuntimeException("error writing way: " + e); } } public void addRelation(long rid, Map tags, LongList wayIds, LongList fromWid, LongList toWid, LongList viaNid) { RelationData r = new RelationData(rid, wayIds); r.setTags((HashMap) tags); try { rListener.nextRelation(r); if (fromWid == null || toWid == null || viaNid == null || viaNid.size() != 1) { // dummy-TR for each viaNid for (int vi = 0; vi < (viaNid == null ? 0 : viaNid.size()); vi++) { rListener.nextRestriction(r, 0L, 0L, viaNid.get(vi)); } return; } for (int fi = 0; fi < fromWid.size(); fi++) { for (int ti = 0; ti < toWid.size(); ti++) { rListener.nextRestriction(r, fromWid.get(fi), toWid.get(ti), viaNid.get(0)); } } } catch (Exception e) { throw new RuntimeException("error writing relation", e); } } }