/** * This program * - reads an *.osm from stdin * - writes 45*30 degree node tiles + a way file + a rel file * * @author ab */ package btools.mapcreator; import java.io.BufferedOutputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Map; import btools.expressions.BExpressionContextNode; import btools.expressions.BExpressionContextWay; import btools.expressions.BExpressionMetaData; public class OsmCutter extends MapCreatorBase { private long recordCnt; private long nodesParsed; private long waysParsed; private long relsParsed; private long changesetsParsed; private DataOutputStream wayDos; private DataOutputStream cyclewayDos; private DataOutputStream restrictionsDos; public WayCutter wayCutter; public RestrictionCutter restrictionCutter; public NodeFilter nodeFilter; Connection conn = null; // PreparedStatement psNoise = null; // PreparedStatement psRiver = null; // PreparedStatement psForest = null; PreparedStatement psAllTags = null; ResultSet rsBrouter = null; int cntHighways = 0; int cntWayModified = 0; int cntNewNoise = 0; int cntNewRiver = 0; int cntNewForest = 0; int cntNewTown = 0; int cntNewTraffic = 0; String jdbcurl; public static void main(String[] args) throws Exception { System.out.println("*** OsmCutter: cut an osm map in node-tiles + a way file"); if (args.length != 6 && args.length != 7) { System.out.println("usage: bzip2 -dc | java OsmCutter "); System.out.println("or : java OsmCutter "); return; } new OsmCutter().process( new File(args[0]) , new File(args[1]) , new File(args[2]) , new File(args[3]) , new File(args[4]) , new File(args[5]) , args.length > 6 ? new File(args[6]) : null ); } private BExpressionContextWay _expctxWay; private BExpressionContextNode _expctxNode; // private BExpressionContextWay _expctxWayStat; // private BExpressionContextNode _expctxNodeStat; public void process(File lookupFile, File outTileDir, File wayFile, File relFile, File resFile, File profileFile, File mapFile) throws Exception { if (!lookupFile.exists()) { throw new IllegalArgumentException("lookup-file: " + lookupFile + " does not exist"); } BExpressionMetaData meta = new BExpressionMetaData(); _expctxWay = new BExpressionContextWay(meta); _expctxNode = new BExpressionContextNode(meta); meta.readMetaData(lookupFile); _expctxWay.parseFile(profileFile, "global"); // _expctxWayStat = new BExpressionContextWay( null ); // _expctxNodeStat = new BExpressionContextNode( null ); this.outTileDir = outTileDir; if (!outTileDir.isDirectory()) throw new RuntimeException("out tile directory " + outTileDir + " does not exist"); wayDos = wayFile == null ? null : new DataOutputStream(new BufferedOutputStream(new FileOutputStream(wayFile))); cyclewayDos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(relFile))); if (resFile != null) { restrictionsDos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(resFile))); } // read the osm map into memory long t0 = System.currentTimeMillis(); new OsmParser().readMap(mapFile, this, this, this); long t1 = System.currentTimeMillis(); System.out.println("parsing time (ms) =" + (t1 - t0)); // close all files closeTileOutStreams(); if (wayDos != null) { wayDos.close(); } cyclewayDos.close(); if (restrictionsDos != null) { restrictionsDos.close(); } // System.out.println( "-------- way-statistics -------- " ); // _expctxWayStat.dumpStatistics(); // System.out.println( "-------- node-statistics -------- " ); // _expctxNodeStat.dumpStatistics(); System.out.println(statsLine()); } private void checkStats() { if ((++recordCnt % 100000) == 0) System.out.println(statsLine()); } private String statsLine() { return "records read: " + recordCnt + " nodes=" + nodesParsed + " ways=" + waysParsed + " rels=" + relsParsed + " changesets=" + changesetsParsed; } public void setJdbcUrl(String url) { this.jdbcurl = url; } @Override public void nextNode(NodeData n) throws Exception { nodesParsed++; checkStats(); if (n.getTagsOrNull() != null) { int[] lookupData = _expctxNode.createNewLookupData(); for (Map.Entry e : n.getTagsOrNull().entrySet()) { _expctxNode.addLookupValue(e.getKey(), e.getValue(), lookupData); // _expctxNodeStat.addLookupValue( key, value, null ); } n.description = _expctxNode.encode(lookupData); } // write node to file int tileIndex = getTileIndex(n.ilon, n.ilat); if (tileIndex >= 0) { n.writeTo(getOutStreamForTile(tileIndex)); if (wayCutter != null) { wayCutter.nextNode(n); } } } private void generatePseudoTags(Map map) { // add pseudo.tags for concrete:lanes and concrete:plates String concrete = null; for (Map.Entry e : map.entrySet()) { String key = e.getKey(); if ("concrete".equals(key)) { return; } if ("surface".equals(key)) { String value = e.getValue(); if (value.startsWith("concrete:")) { concrete = value.substring("concrete:".length()); } } } if (concrete != null) { map.put("concrete", concrete); } } // Ess Bee : NEW function to add the new tags (estimated_noise_class , river, forest...) private void generateSpecialTags(long osm_id, Map map) { if (jdbcurl == null) return; // is the database allready connected? if (conn == null) { String sql_all_tags = "SELECT * from all_tags where losmid = ?"; System.err.println("OsmCutter start connection to the database........" + jdbcurl); try { conn = DriverManager.getConnection(jdbcurl); psAllTags = conn.prepareStatement(sql_all_tags); System.err.println("OsmCutter connect to the database ok........"); } catch (SQLException g) { System.err.format("Osm Cutter SQL State: %s\n%s\n", g.getSQLState(), g.getMessage()); System.exit(1); return; } catch (Exception f) { f.printStackTrace(); System.exit(1); return; } } for (Map.Entry e : map.entrySet()) { if (e.getKey().equals("highway")) { cntHighways = cntHighways + 1; try { psAllTags.setLong(1, osm_id); // process the results rsBrouter = psAllTags.executeQuery(); if (rsBrouter.next()) { cntWayModified = cntWayModified + 1; if (rsBrouter.getString("noise_class") != null) { map.put("estimated_noise_class", rsBrouter.getString("noise_class")); cntNewNoise = cntNewNoise + 1; } if (rsBrouter.getString("river_class") != null) { map.put("estimated_river_class", rsBrouter.getString("river_class")); cntNewRiver = cntNewRiver + 1; } if (rsBrouter.getString("forest_class") != null) { map.put("estimated_forest_class", rsBrouter.getString("forest_class")); cntNewForest = cntNewForest + 1; } if (rsBrouter.getString("town_class") != null) { map.put("estimated_town_class", rsBrouter.getString("town_class")); cntNewTown = cntNewTown + 1; } if (rsBrouter.getString("traffic_class") != null) { map.put("estimated_traffic_class", rsBrouter.getString("traffic_class")); cntNewTraffic = cntNewTraffic + 1; } } if ((cntHighways % 100000) == 0) { System.out.print("HW processed=" + cntHighways + " HW modifs=" + cntWayModified + " NoiseTags=" + cntNewNoise); System.out.println(" RiverTags=" + cntNewRiver + " ForestTags=" + cntNewForest + " TownTags=" + cntNewTown + " TrafficTags=" + cntNewTraffic); } } catch (SQLException g) { System.err.format(" OsmCutter execute sql .. SQL State: %s\n%s\n", g.getSQLState(), g.getMessage()); System.exit(1); } catch (Exception f) { f.printStackTrace(); System.exit(1); } return; } } } @Override public void nextWay(WayData w) throws Exception { waysParsed++; checkStats(); // encode tags if (w.getTagsOrNull() == null) return; generateSpecialTags(w.wid, w.getTagsOrNull()); generatePseudoTags(w.getTagsOrNull()); int[] lookupData = _expctxWay.createNewLookupData(); for (String key : w.getTagsOrNull().keySet()) { String value = w.getTag(key); _expctxWay.addLookupValue(key, value.replace(' ', '_'), lookupData); } w.description = _expctxWay.encode(lookupData); if (w.description == null) return; // filter according to profile _expctxWay.evaluate(false, w.description); boolean ok = _expctxWay.getCostfactor() < 10000.; _expctxWay.evaluate(true, w.description); ok |= _expctxWay.getCostfactor() < 10000.; if (!ok) return; if (wayDos != null) { w.writeTo(wayDos); } if (wayCutter != null) { wayCutter.nextWay(w); } if (nodeFilter != null) { nodeFilter.nextWay(w); } } @Override public void nextRelation(RelationData r) throws IOException { relsParsed++; checkStats(); String route = r.getTag("route"); // filter out non-cycle relations if (route == null) { return; } String network = r.getTag("network"); if (network == null) network = ""; String state = r.getTag("state"); if (state == null) state = ""; writeId(cyclewayDos, r.rid); cyclewayDos.writeUTF(route); cyclewayDos.writeUTF(network); cyclewayDos.writeUTF(state); for (int i = 0; i < r.ways.size(); i++) { long wid = r.ways.get(i); writeId(cyclewayDos, wid); } writeId(cyclewayDos, -1); } @Override public void nextRestriction(RelationData r, long fromWid, long toWid, long viaNid) throws Exception { String type = r.getTag("type"); if (type == null || !"restriction".equals(type)) { return; } short exceptions = 0; String except = r.getTag("except"); if (except != null) { exceptions |= toBit("bicycle", 0, except); exceptions |= toBit("motorcar", 1, except); exceptions |= toBit("agricultural", 2, except); exceptions |= toBit("forestry", 2, except); exceptions |= toBit("psv", 3, except); exceptions |= toBit("hgv", 4, except); } for (String restrictionKey : r.getTagsOrNull().keySet()) { if (!(restrictionKey.equals("restriction") || restrictionKey.startsWith("restriction:"))) { continue; } String restriction = r.getTag(restrictionKey); RestrictionData res = new RestrictionData(); res.restrictionKey = restrictionKey; res.restriction = restriction; res.exceptions = exceptions; res.fromWid = fromWid; res.toWid = toWid; res.viaNid = viaNid; if (restrictionsDos != null) { res.writeTo(restrictionsDos); } if (restrictionCutter != null) { restrictionCutter.nextRestriction(res); } } } private static short toBit(String tag, int bitpos, String s) { return (short) (s.indexOf(tag) < 0 ? 0 : 1 << bitpos); } private int getTileIndex(int ilon, int ilat) { int lon = ilon / 45000000; int lat = ilat / 30000000; if (lon < 0 || lon > 7 || lat < 0 || lat > 5) { System.out.println("warning: ignoring illegal pos: " + ilon + "," + ilat); return -1; } return lon * 6 + lat; } protected String getNameForTile(int tileIndex) { int lon = (tileIndex / 6) * 45 - 180; int lat = (tileIndex % 6) * 30 - 90; String slon = lon < 0 ? "W" + (-lon) : "E" + lon; String slat = lat < 0 ? "S" + (-lat) : "N" + lat; return slon + "_" + slat + ".ntl"; } }