/** * Container for link between two Osm nodes (pre-pocessor version) * * @author ab */ package btools.mapcreator; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.EOFException; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import btools.expressions.BExpressionContextWay; import btools.util.CheapRuler; import btools.util.CompactLongMap; import btools.util.FrozenLongMap; public class OsmTrafficMap { int minLon; int minLat; int maxLon; int maxLat; private BExpressionContextWay expctxWay; private OsmTrafficMap oldTrafficClasses; private DataOutputStream newTrafficDos; private File oldTrafficFile; private File newTrafficFile; private int totalChanges = 0; private int supressedChanges = 0; private boolean doNotAdd = false; private boolean debug = false; public OsmTrafficMap( BExpressionContextWay expctxWay ) { this.expctxWay = expctxWay; debug = Boolean.getBoolean( "debugTrafficMap" ); } public static class OsmTrafficElement { public long node2; public int traffic; public OsmTrafficElement next; } private CompactLongMap map = new CompactLongMap(); public void loadAll( File file, int minLon, int minLat, int maxLon, int maxLat, boolean includeMotorways ) throws Exception { load( file, minLon, minLat, maxLon, maxLat, includeMotorways ); // check for old traffic data oldTrafficFile = new File( file.getParentFile(), file.getName() + "_old" ); if ( oldTrafficFile.exists() ) { oldTrafficClasses = new OsmTrafficMap( null ); oldTrafficClasses.doNotAdd = true; oldTrafficClasses.load( oldTrafficFile, minLon, minLat, maxLon, maxLat, false ); } // check for old traffic data newTrafficFile = new File( file.getParentFile(), file.getName() + "_new" ); newTrafficDos = new DataOutputStream( new BufferedOutputStream( new FileOutputStream( newTrafficFile ) ) ); } public void finish() throws Exception { if ( newTrafficDos != null ) { newTrafficDos.close(); newTrafficDos = null; oldTrafficFile.delete(); newTrafficFile.renameTo( oldTrafficFile ); System.out.println( "TrafficMap: changes total=" + totalChanges + " supressed=" + supressedChanges ); } } public void load( File file, int minLon, int minLat, int maxLon, int maxLat, boolean includeMotorways ) throws Exception { this.minLon = minLon; this.minLat = minLat; this.maxLon = maxLon; this.maxLat = maxLat; int trafficElements = 0; DataInputStream is = new DataInputStream( new BufferedInputStream( new FileInputStream( file ) ) ); try { for(;;) { long n1 = is.readLong(); long n2 = is.readLong(); int traffic = is.readInt(); if ( traffic == -1 && !includeMotorways ) { continue; } if ( isInsideBounds( n1 ) || isInsideBounds( n2 ) ) { if ( addElement( n1, n2, traffic ) ) { trafficElements++; } } } } catch( EOFException eof ) {} finally{ is.close(); } map = new FrozenLongMap( map ); System.out.println( "read traffic-elements: " + trafficElements ); } public boolean addElement( long n1, long n2, int traffic ) { OsmTrafficElement e = getElement( n1, n2 ); if ( e == null ) { e = new OsmTrafficElement(); e.node2 = n2; e.traffic = traffic; OsmTrafficElement e0 = map.get( n1 ); if ( e0 != null ) { while( e0.next != null ) { e0 = e0.next; } e0.next = e; } else { map.fastPut( n1, e ); } return true; } if ( doNotAdd ) { e.traffic = Math.max( e.traffic, traffic ); } else { e.traffic = e.traffic == -1 || traffic == -1 ? -1 : e.traffic + traffic; } return false; } private boolean isInsideBounds( long id ) { int ilon = (int)(id >> 32); int ilat = (int)(id & 0xffffffff); return ilon >= minLon && ilon < maxLon && ilat >= minLat && ilat < maxLat; } public int getTrafficClass( long n1, long n2 ) { // used for the old data, where we stpre traffic-classes, not volumes OsmTrafficElement e = getElement( n1, n2 ); return e == null ? 0 : e.traffic; } public int getTrafficClassForTraffic( int traffic ) { if ( traffic < 0 ) return -1; if ( traffic < 40000 ) return 0; if ( traffic < 80000 ) return 2; if ( traffic < 160000 ) return 3; if ( traffic < 320000 ) return 4; if ( traffic < 640000 ) return 5; if ( traffic <1280000 ) return 6; return 7; } private int getTraffic( long n1, long n2 ) { OsmTrafficElement e1 = getElement( n1, n2 ); int traffic1 = e1 == null ? 0 : e1.traffic; OsmTrafficElement e2 = getElement( n2, n1 ); int traffic2 = e2 == null ? 0 : e2.traffic; return traffic1 == -1 || traffic2 == -1 ? -1 : traffic1 > traffic2 ? traffic1 : traffic2; } public void freeze() { } private OsmTrafficElement getElement( long n1, long n2 ) { OsmTrafficElement e = map.get( n1 ); while( e != null ) { if ( e.node2 == n2 ) { return e; } e = e.next; } return null; } public OsmTrafficElement getElement( long n ) { return map.get( n ); } public byte[] addTrafficClass( ArrayList linkNodes, byte[] description ) throws IOException { double distance = 0.; double sum = 0.; for( int i=0; i" + trafficClass + " supress=" + supressChange ); } if ( supressChange ) { trafficClass = oldTrafficClass; supressedChanges++; } } } if ( trafficClass > 0 ) { newTrafficDos.writeLong( id0 ); newTrafficDos.writeLong( id1 ); newTrafficDos.writeInt( trafficClass ); expctxWay.decode( description ); expctxWay.addLookupValue( "estimated_traffic_class", trafficClass + 1 ); return expctxWay.encode(); } return description; } }