package btools.mapcreator; import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.EOFException; import java.io.File; import java.io.FileInputStream; import btools.util.DenseLongMap; import btools.util.TinyDenseLongMap; /** * WayCutter5 does 2 step in map-processing: *

* - cut the 45*30 way files into 5*5 pieces * - create a file containing all border node ids * * @author ab */ public class WayCutter5 extends MapCreatorBase { private DataOutputStream borderNidsOutStream; private DenseLongMap tileIndexMap; private File nodeTilesIn; private int lonoffset; private int latoffset; public RelationMerger relMerger; public NodeFilter nodeFilter; public NodeCutter nodeCutter; public RestrictionCutter5 restrictionCutter5; public static void main(String[] args) throws Exception { System.out.println("*** WayCutter5: Soft-Cut way-data into tiles"); if (args.length != 4) { System.out.println("usage: java WayCutter5 "); return; } new WayCutter5().process(new File(args[0]), new File(args[1]), new File(args[2]), new File(args[3])); } public void process(File nodeTilesIn, File wayTilesIn, File wayTilesOut, File borderNidsOut) throws Exception { this.nodeTilesIn = nodeTilesIn; this.outTileDir = wayTilesOut; borderNidsOutStream = createOutStream(borderNidsOut); new WayIterator(this, true).processDir(wayTilesIn, ".wtl"); borderNidsOutStream.close(); } @Override public boolean wayFileStart(File wayfile) throws Exception { // read corresponding node-file into tileIndexMap String name = wayfile.getName(); String nodefilename = name.substring(0, name.length() - 3) + "ntl"; File nodefile = new File(nodeTilesIn, nodefilename); tileIndexMap = Boolean.getBoolean("useDenseMaps") ? new DenseLongMap() : new TinyDenseLongMap(); lonoffset = -1; latoffset = -1; if (nodeCutter != null) { nodeCutter.nodeFileStart(null); } new NodeIterator(this, nodeCutter != null).processFile(nodefile); if (restrictionCutter5 != null) { String resfilename = name.substring(0, name.length() - 3) + "rtl"; File resfile = new File("restrictions", resfilename); if (resfile.exists()) { // read restrictions for nodes in nodesMap DataInputStream di = new DataInputStream(new BufferedInputStream(new FileInputStream(resfile))); int ntr = 0; try { for (; ; ) { RestrictionData res = new RestrictionData(di); restrictionCutter5.nextRestriction(res); ntr++; } } catch (EOFException eof) { di.close(); } System.out.println("read " + ntr + " turn-restrictions"); } } return true; } @Override public void nextNode(NodeData n) throws Exception { if (nodeFilter != null) { if (!nodeFilter.isRelevant(n)) { return; } } if (nodeCutter != null) { nodeCutter.nextNode(n); } tileIndexMap.put(n.nid, getTileIndex(n.ilon, n.ilat)); } @Override public void nextWay(WayData data) throws Exception { long waytileset = 0; int nnodes = data.nodes.size(); int[] tiForNode = new int[nnodes]; // determine the tile-index for each node for (int i = 0; i < nnodes; i++) { int tileIndex = tileIndexMap.getInt(data.nodes.get(i)); if (tileIndex != -1) { waytileset |= (1L << tileIndex); } tiForNode[i] = tileIndex; } if (relMerger != null) { relMerger.nextWay(data); } // now write way to all tiles hit for (int tileIndex = 0; tileIndex < 54; tileIndex++) { if ((waytileset & (1L << tileIndex)) == 0) { continue; } data.writeTo(getOutStreamForTile(tileIndex)); } // and write edge nodes to the border-nid file for (int i = 0; i < nnodes; i++) { int ti = tiForNode[i]; if (ti != -1) { if ((i > 0 && tiForNode[i - 1] != ti) || (i + 1 < nnodes && tiForNode[i + 1] != ti)) { writeId(borderNidsOutStream, data.nodes.get(i)); } } } } @Override public void wayFileEnd(File wayFile) throws Exception { closeTileOutStreams(); if (nodeCutter != null) { nodeCutter.nodeFileEnd(null); } if (restrictionCutter5 != null) { restrictionCutter5.finish(); } } public int getTileIndexForNid(long nid) { return tileIndexMap.getInt(nid); } private int getTileIndex(int ilon, int ilat) { int lonoff = (ilon / 45000000) * 45; int latoff = (ilat / 30000000) * 30; if (lonoffset == -1) lonoffset = lonoff; if (latoffset == -1) latoffset = latoff; if (lonoff != lonoffset || latoff != latoffset) throw new IllegalArgumentException("inconsistent node: " + ilon + " " + ilat); int lon = (ilon / 5000000) % 9; int lat = (ilat / 5000000) % 6; if (lon < 0 || lon > 8 || lat < 0 || lat > 5) throw new IllegalArgumentException("illegal pos: " + ilon + "," + ilat); return lon * 6 + lat; } protected String getNameForTile(int tileIndex) { int lon = (tileIndex / 6) * 5 + lonoffset - 180; int lat = (tileIndex % 6) * 5 + latoffset - 90; String slon = lon < 0 ? "W" + (-lon) : "E" + lon; String slat = lat < 0 ? "S" + (-lat) : "N" + lat; return slon + "_" + slat + ".wt5"; } }