Traffic simulation patch
This commit is contained in:
parent
a35eea8878
commit
91c809e05c
22 changed files with 1595 additions and 83 deletions
|
|
@ -34,14 +34,12 @@ public class OsmNodeP extends OsmLinkP implements Comparable<OsmNodeP>
|
|||
*/
|
||||
public short selev;
|
||||
|
||||
public boolean isBorder = false;
|
||||
|
||||
public final static int NO_BRIDGE_BIT = 1;
|
||||
public final static int NO_TUNNEL_BIT = 2;
|
||||
public final static int LCN_BIT = 4;
|
||||
public final static int CR_BIT = 8;
|
||||
public final static int BORDER_BIT = 4;
|
||||
public final static int TRAFFIC_BIT = 8;
|
||||
|
||||
public byte wayBits = 0;
|
||||
public byte bits = 0;
|
||||
|
||||
// interface OsmPos
|
||||
public int getILat()
|
||||
|
|
@ -57,7 +55,7 @@ public class OsmNodeP extends OsmLinkP implements Comparable<OsmNodeP>
|
|||
public short getSElev()
|
||||
{
|
||||
// if all bridge or all tunnel, elevation=no-data
|
||||
return ( wayBits & NO_BRIDGE_BIT ) == 0 || ( wayBits & NO_TUNNEL_BIT ) == 0 ? Short.MIN_VALUE : selev;
|
||||
return ( bits & NO_BRIDGE_BIT ) == 0 || ( bits & NO_TUNNEL_BIT ) == 0 ? Short.MIN_VALUE : selev;
|
||||
}
|
||||
|
||||
public double getElev()
|
||||
|
|
@ -247,9 +245,19 @@ public class OsmNodeP extends OsmLinkP implements Comparable<OsmNodeP>
|
|||
return ((long)ilon)<<32 | ilat;
|
||||
}
|
||||
|
||||
public boolean isBorderNode()
|
||||
{
|
||||
return (bits & BORDER_BIT) != 0;
|
||||
}
|
||||
|
||||
public boolean hasTraffic()
|
||||
{
|
||||
return (bits & TRAFFIC_BIT) != 0;
|
||||
}
|
||||
|
||||
public boolean isTransferNode()
|
||||
{
|
||||
return (!isBorder) && _linkCnt() == 2;
|
||||
return (bits & BORDER_BIT) == 0 && _linkCnt() == 2;
|
||||
}
|
||||
|
||||
private int _linkCnt()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,158 @@
|
|||
/**
|
||||
* Container for link between two Osm nodes (pre-pocessor version)
|
||||
*
|
||||
* @author ab
|
||||
*/
|
||||
package btools.mapcreator;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
|
||||
import btools.util.CompactLongMap;
|
||||
import btools.util.FrozenLongMap;
|
||||
|
||||
|
||||
public class OsmTrafficMap
|
||||
{
|
||||
int minLon;
|
||||
int minLat;
|
||||
int maxLon;
|
||||
int maxLat;
|
||||
|
||||
public static class OsmTrafficElement
|
||||
{
|
||||
public long node2;
|
||||
public int traffic;
|
||||
public OsmTrafficElement next;
|
||||
}
|
||||
|
||||
private CompactLongMap<OsmTrafficElement> map = new CompactLongMap<OsmTrafficElement>();
|
||||
|
||||
public long[] 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(); }
|
||||
|
||||
FrozenLongMap fmap = new FrozenLongMap<OsmTrafficElement>( map );
|
||||
map = fmap;
|
||||
System.out.println( "read traffic-elements: " + trafficElements );
|
||||
return fmap.getKeyArray();
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
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 )
|
||||
{
|
||||
int traffic1 = getTraffic( n1, n2 );
|
||||
int traffic2 = getTraffic( n2, n1 );
|
||||
int traffic = traffic1 == -1 || traffic2 == -1 ? -1 : traffic1 > traffic2 ? traffic1 : traffic2;
|
||||
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 < 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 e = getElement( n1, n2 );
|
||||
return e == null ? 0 : e.traffic;
|
||||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
package btools.mapcreator;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
|
||||
import btools.util.Raster2Png;
|
||||
|
||||
public class TrafficData2Png
|
||||
{
|
||||
private static int minLon;
|
||||
private static int minLat;
|
||||
private static int maxLon;
|
||||
private static int maxLat;
|
||||
private static int ncols;
|
||||
private static int nrows;
|
||||
private static int[] pixels;
|
||||
|
||||
public static void main( String[] args) throws Exception
|
||||
{
|
||||
if ( args.length == 8 )
|
||||
{
|
||||
doConvert( args[0], args[1],
|
||||
Double.parseDouble( args[2] ), Double.parseDouble( args[3] ), Double.parseDouble( args[4] ), Double.parseDouble( args[5] ),
|
||||
Integer.parseInt( args[6] ), Integer.parseInt( args[7] ) );
|
||||
}
|
||||
else if ( args.length == 4 )
|
||||
{
|
||||
int lon0 = Integer.parseInt( args[0] );
|
||||
int lat0 = Integer.parseInt( args[1] );
|
||||
String inputFile = "traffic/E" + lon0 + "_N" + lat0 + ".trf";
|
||||
for( int lon = lon0; lon < lon0+5; lon++ )
|
||||
for( int lat = lat0; lat < lat0+5; lat++ )
|
||||
{
|
||||
String imageFile = "traffic_pics/E" + lon + "_N" + lat + ".png";
|
||||
System.out.println( "file=" + inputFile + " image=" + imageFile );
|
||||
doConvert( inputFile, imageFile, lon, lat, lon+1, lat+1, Integer.parseInt( args[2] ), Integer.parseInt( args[3] ) );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void doConvert( String inputFile, String imageFile, double lon0, double lat0, double lon1, double lat1,
|
||||
int cols, int rows ) throws Exception
|
||||
{
|
||||
OsmTrafficMap trafficMap = new OsmTrafficMap();
|
||||
minLon = (int)(lon0 * 1000000 + 180000000);
|
||||
maxLon = (int)(lon1 * 1000000 + 180000000);
|
||||
minLat = (int)(lat0 * 1000000 + 90000000);
|
||||
maxLat = (int)(lat1 * 1000000 + 90000000);
|
||||
ncols = cols;
|
||||
nrows = rows;
|
||||
|
||||
long[] keys = trafficMap.load( new File( inputFile ), minLon, minLat, maxLon, maxLat, true );
|
||||
|
||||
pixels = new int[cols*rows];
|
||||
|
||||
int[] tclasses = new int[] { 1,2,3,4,5,6,7, -1 };
|
||||
for( int tclass : tclasses )
|
||||
{
|
||||
for(long key : keys )
|
||||
{
|
||||
OsmTrafficMap.OsmTrafficElement e = trafficMap.getElement(key );
|
||||
while( e != null )
|
||||
{
|
||||
long key2 = e.node2;
|
||||
e = e.next;
|
||||
int trafficClass = trafficMap.getTrafficClass( key, key2 );
|
||||
if ( trafficClass != tclass ) continue;
|
||||
|
||||
int[] from = getImagePosition( key );
|
||||
int[] to = getImagePosition( key2 );
|
||||
|
||||
int rgb = 0;
|
||||
if ( trafficClass == -1 ) rgb = 0x0000ff; // blue
|
||||
else if ( trafficClass == 1 ) rgb = 0x404040; // dark grey
|
||||
else if ( trafficClass == 2 ) rgb = 0xa0a0a0; // light grey
|
||||
else if ( trafficClass == 3 ) rgb = 0x00ff00; // green
|
||||
else if ( trafficClass == 4 ) rgb = 0xf4e500; // yellow
|
||||
else if ( trafficClass == 5 ) rgb = 0xf18e1c; // orange
|
||||
else if ( trafficClass == 6 ) rgb = 0xe32322; // red
|
||||
else if ( trafficClass == 7 ) rgb = 0xc0327d; // pink
|
||||
if ( rgb != 0 )
|
||||
{
|
||||
drawLine( from, to, rgb );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Raster2Png r2p = new Raster2Png( Raster2Png.FILTER_NONE, 6, cols, rows, pixels );
|
||||
byte[] png = r2p.pngEncode( );
|
||||
|
||||
System.out.println( "got png of size: " + png.length );
|
||||
DataOutputStream dos = new DataOutputStream( new BufferedOutputStream( new FileOutputStream( imageFile ) ) );
|
||||
dos.write(png);
|
||||
dos.close();
|
||||
}
|
||||
|
||||
private static void drawLine( int[] from, int[] to, int rgb )
|
||||
{
|
||||
int ix = from[0];
|
||||
int iy = from[1];
|
||||
int ixx = to[0];
|
||||
int iyy = to[1];
|
||||
|
||||
int sx = ixx > ix ? 1 : -1;
|
||||
int sy = iyy > iy ? 1 : -1;
|
||||
|
||||
int dx = (ixx-ix)*sx;
|
||||
int dy = (iyy-iy)*sy;
|
||||
|
||||
int sum = 0;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
drawPixel( ix, iy, rgb );
|
||||
if ( ix == ixx && iy == iyy ) break;
|
||||
|
||||
if ( Math.abs( sum+dx ) < Math.abs( sum-dy ) )
|
||||
{
|
||||
iy+= sy;
|
||||
sum += dx;
|
||||
}
|
||||
else
|
||||
{
|
||||
ix+= sx;
|
||||
sum -= dy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void drawPixel( int ix, int iy, int rgb )
|
||||
{
|
||||
if ( ix >= 0 && ix < ncols && iy >= 0 && iy < nrows )
|
||||
{
|
||||
pixels[ (nrows-1-iy)*ncols + ix ] = rgb;
|
||||
}
|
||||
}
|
||||
|
||||
private static int[] getImagePosition( long key )
|
||||
{
|
||||
int ilon = (int)(key >> 32);
|
||||
int ilat = (int)(key & 0xffffffff);
|
||||
double lonDelta = maxLon-minLon;
|
||||
double latDelta = maxLat-minLat;
|
||||
int[] res = new int[2];
|
||||
res[0] = (int)( ( (ilon-minLon)/lonDelta ) *ncols );
|
||||
res[1] = (int)( ( (ilat-minLat)/latDelta ) *nrows );
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,12 @@
|
|||
package btools.mapcreator;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
|
@ -31,6 +35,7 @@ import btools.util.LazyArrayOfLists;
|
|||
public class WayLinker extends MapCreatorBase
|
||||
{
|
||||
private File nodeTilesIn;
|
||||
private File trafficTilesIn;
|
||||
private File dataTilesOut;
|
||||
private File borderFileIn;
|
||||
|
||||
|
|
@ -39,6 +44,7 @@ public class WayLinker extends MapCreatorBase
|
|||
private boolean readingBorder;
|
||||
|
||||
private CompactLongMap<OsmNodeP> nodesMap;
|
||||
private OsmTrafficMap trafficMap;
|
||||
private List<OsmNodeP> nodesList;
|
||||
private CompactLongSet borderSet;
|
||||
private short lookupVersion;
|
||||
|
|
@ -77,6 +83,7 @@ public class WayLinker extends MapCreatorBase
|
|||
public void process( File nodeTilesIn, File wayTilesIn, File borderFileIn, File lookupFile, File profileFile, File dataTilesOut, String dataTilesSuffix ) throws Exception
|
||||
{
|
||||
this.nodeTilesIn = nodeTilesIn;
|
||||
this.trafficTilesIn = new File( "traffic" );
|
||||
this.dataTilesOut = dataTilesOut;
|
||||
this.borderFileIn = borderFileIn;
|
||||
this.dataTilesSuffix = dataTilesSuffix;
|
||||
|
|
@ -126,6 +133,14 @@ public class WayLinker extends MapCreatorBase
|
|||
nodesMap = nodesMapFrozen;
|
||||
nodesList = nodesMapFrozen.getValueList();
|
||||
}
|
||||
|
||||
// read a traffic-file, if any
|
||||
File trafficFile = fileFromTemplate( wayfile, trafficTilesIn, "trf" );
|
||||
if ( trafficFile.exists() )
|
||||
{
|
||||
trafficMap = new OsmTrafficMap();
|
||||
trafficMap.load( trafficFile, minLon, minLat, minLon + 5000000, minLat + 5000000, false );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -135,7 +150,7 @@ public class WayLinker extends MapCreatorBase
|
|||
n.ilon = data.ilon;
|
||||
n.ilat = data.ilat;
|
||||
n.selev = data.selev;
|
||||
n.isBorder = readingBorder;
|
||||
|
||||
if ( readingBorder || (!borderSet.contains( data.nid )) )
|
||||
{
|
||||
nodesMap.fastPut( data.nid, n );
|
||||
|
|
@ -143,6 +158,7 @@ public class WayLinker extends MapCreatorBase
|
|||
|
||||
if ( readingBorder )
|
||||
{
|
||||
n.bits |= OsmNodeP.BORDER_BIT;
|
||||
borderSet.fastAdd( data.nid );
|
||||
return;
|
||||
}
|
||||
|
|
@ -160,6 +176,7 @@ public class WayLinker extends MapCreatorBase
|
|||
public void nextWay( WayData way ) throws Exception
|
||||
{
|
||||
byte[] description = abUnifier.unify( way.description );
|
||||
int lastTraffic = 0;
|
||||
|
||||
// filter according to profile
|
||||
expctxWay.evaluate( false, description, null );
|
||||
|
|
@ -183,11 +200,20 @@ public class WayLinker extends MapCreatorBase
|
|||
if ( n1 != null && n2 != null && n1 != n2 )
|
||||
{
|
||||
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;
|
||||
}
|
||||
link.descriptionBitmap = description;
|
||||
}
|
||||
if ( n2 != null )
|
||||
{
|
||||
n2.wayBits |= wayBits;
|
||||
n2.bits |= wayBits;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -197,6 +223,7 @@ public class WayLinker extends MapCreatorBase
|
|||
{
|
||||
nodesMap = null;
|
||||
borderSet = null;
|
||||
trafficMap = null;
|
||||
|
||||
byte[] abBuf = new byte[1024*1024];
|
||||
byte[] abBuf2 = new byte[10*1024*1024];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue