From 010383e7e7b7b92471f92d5f8a17046147e5c034 Mon Sep 17 00:00:00 2001 From: Arndt Brenschede Date: Sat, 1 Feb 2020 19:48:53 +0100 Subject: [PATCH] traffic simulation delta supression --- .../main/java/btools/mapcreator/OsmNodeP.java | 15 +- .../java/btools/mapcreator/OsmTrafficMap.java | 128 ++++++++++++++++-- .../java/btools/mapcreator/WayLinker.java | 20 +-- 3 files changed, 135 insertions(+), 28 deletions(-) diff --git a/brouter-map-creator/src/main/java/btools/mapcreator/OsmNodeP.java b/brouter-map-creator/src/main/java/btools/mapcreator/OsmNodeP.java index 1fa1fd0..936072f 100644 --- a/brouter-map-creator/src/main/java/btools/mapcreator/OsmNodeP.java +++ b/brouter-map-creator/src/main/java/btools/mapcreator/OsmNodeP.java @@ -102,12 +102,12 @@ public class OsmNodeP extends OsmLinkP return null; } - public void writeNodeData( MicroCache mc ) throws IOException + public void writeNodeData( MicroCache mc, OsmTrafficMap trafficMap ) throws IOException { boolean valid = true; if ( mc instanceof MicroCache2 ) { - valid = writeNodeData2( (MicroCache2) mc ); + valid = writeNodeData2( (MicroCache2) mc, trafficMap ); } else throw new IllegalArgumentException( "unknown cache version: " + mc.getClass() ); @@ -167,7 +167,7 @@ public class OsmNodeP extends OsmLinkP } } - public boolean writeNodeData2( MicroCache2 mc ) throws IOException + public boolean writeNodeData2( MicroCache2 mc, OsmTrafficMap trafficMap ) throws IOException { boolean hasLinks = false; @@ -245,11 +245,18 @@ public class OsmNodeP extends OsmLinkP } } + // add traffic simulation, if present + byte[] description = link0.descriptionBitmap; + if ( trafficMap != null ) + { + description = trafficMap.addTrafficClass( linkNodes, description ); + } + // write link data int sizeoffset = mc.writeSizePlaceHolder(); mc.writeVarLengthSigned( target.ilon - ilon ); mc.writeVarLengthSigned( target.ilat - ilat ); - mc.writeModeAndDesc( isReverse, link0.descriptionBitmap ); + mc.writeModeAndDesc( isReverse, description ); if ( !isReverse && linkNodes.size() > 2 ) // write geometry for forward links only { DPFilter.doDPFilter( linkNodes ); diff --git a/brouter-map-creator/src/main/java/btools/mapcreator/OsmTrafficMap.java b/brouter-map-creator/src/main/java/btools/mapcreator/OsmTrafficMap.java index 8b417ce..4442adf 100644 --- a/brouter-map-creator/src/main/java/btools/mapcreator/OsmTrafficMap.java +++ b/brouter-map-creator/src/main/java/btools/mapcreator/OsmTrafficMap.java @@ -6,11 +6,18 @@ 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; @@ -22,6 +29,21 @@ public class OsmTrafficMap int maxLon; int maxLat; + private BExpressionContextWay expctxWay; + + private OsmTrafficMap oldTrafficClasses; + private DataOutputStream newTrafficDos; + private File oldTrafficFile; + private File newTrafficFile; + + int totalChanges = 0; + int supressedChanges = 0; + + public OsmTrafficMap( BExpressionContextWay expctxWay ) + { + this.expctxWay = expctxWay; + } + public static class OsmTrafficElement { public long node2; @@ -31,7 +53,36 @@ public class OsmTrafficMap private CompactLongMap map = new CompactLongMap(); - public long[] load( File file, int minLon, int minLat, int maxLon, int maxLat, boolean includeMotorways ) throws Exception + 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.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; @@ -63,10 +114,8 @@ public class OsmTrafficMap catch( EOFException eof ) {} finally{ is.close(); } - FrozenLongMap fmap = new FrozenLongMap( map ); - map = fmap; + map = new FrozenLongMap( map ); System.out.println( "read traffic-elements: " + trafficElements ); - return fmap.getKeyArray(); } @@ -108,17 +157,14 @@ public class OsmTrafficMap public int getTrafficClass( long n1, long n2 ) { - int traffic1 = getTraffic( n1, n2 ); - int traffic2 = getTraffic( n2, n1 ); - int traffic = traffic1 == -1 || traffic2 == -1 ? -1 : traffic1 > traffic2 ? traffic1 : traffic2; + int traffic = getTraffic( n1, n2 ); return getTrafficClassForTraffic( traffic ); } public int getTrafficClassForTraffic( int traffic ) { if ( traffic < 0 ) return -1; - if ( traffic < 20000 ) return 0; - if ( traffic < 40000 ) return 1; + if ( traffic < 40000 ) return 0; if ( traffic < 80000 ) return 2; if ( traffic < 160000 ) return 3; if ( traffic < 320000 ) return 4; @@ -129,8 +175,11 @@ public class OsmTrafficMap private int getTraffic( long n1, long n2 ) { - OsmTrafficElement e = getElement( n1, n2 ); - return e == null ? 0 : e.traffic; + 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() @@ -155,4 +204,61 @@ public class OsmTrafficMap { return map.get( n ); } + + public byte[] addTrafficClass( ArrayList linkNodes, byte[] description ) throws IOException + { + double distance = 0.; + double sum = 0.; + + for( int i=0; i 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; + } + } diff --git a/brouter-map-creator/src/main/java/btools/mapcreator/WayLinker.java b/brouter-map-creator/src/main/java/btools/mapcreator/WayLinker.java index f7bda8f..58bd280 100644 --- a/brouter-map-creator/src/main/java/btools/mapcreator/WayLinker.java +++ b/brouter-map-creator/src/main/java/btools/mapcreator/WayLinker.java @@ -306,7 +306,7 @@ public class WayLinker extends MapCreatorBase implements Runnable // read a traffic-file, if any if ( trafficFile.exists() ) { - trafficMap = new OsmTrafficMap(); + trafficMap = new OsmTrafficMap( expctxWay ); trafficMap.load( trafficFile, minLon, minLat, minLon + 5000000, minLat + 5000000, false ); } return true; @@ -386,7 +386,6 @@ public class WayLinker extends MapCreatorBase implements Runnable public void nextWay( WayData way ) throws Exception { byte[] description = abUnifier.unify( way.description ); - int lastTraffic = 0; // filter according to profile expctxWay.evaluate( false, description ); @@ -417,15 +416,6 @@ public class WayLinker extends MapCreatorBase implements Runnable OsmLinkP link = n2.createLink( n1 ); - int traffic = trafficMap == null ? 0 : trafficMap.getTrafficClass( n1.getIdFromPos(), n2.getIdFromPos() ); - if ( traffic != lastTraffic ) - { - expctxWay.decode( description ); - expctxWay.addLookupValue( "estimated_traffic_class", traffic == 0 ? 0 : traffic + 1 ); - description = abUnifier.unify( expctxWay.encode() ); - lastTraffic = traffic; - n1.incWayCount(); // force network node due to description change - } link.descriptionBitmap = description; if ( n1.ilon / cellsize != n2.ilon / cellsize || n1.ilat / cellsize != n2.ilat / cellsize ) @@ -450,7 +440,6 @@ public class WayLinker extends MapCreatorBase implements Runnable nodesMap = null; borderSet = null; - trafficMap = null; byte[] abBuf1 = new byte[10 * 1024 * 1024]; byte[] abBuf2 = new byte[10 * 1024 * 1024]; @@ -552,7 +541,7 @@ public class WayLinker extends MapCreatorBase implements Runnable for ( OsmNodeP n : sortedList.values() ) { - n.writeNodeData( mc ); + n.writeNodeData( mc, trafficMap ); } if ( mc.getSize() > 0 ) { @@ -623,6 +612,11 @@ public class WayLinker extends MapCreatorBase implements Runnable ra.write( abFileIndex, 0, abFileIndex.length ); ra.close(); } + if ( trafficMap != null ) + { + trafficMap.finish(); + trafficMap = null; + } System.out.println( "**** codec stats: *******\n" + StatCoderContext.getBitReport() ); }