initial commit of BRouter Version 0.98
This commit is contained in:
parent
e4ae2b37d3
commit
91e62f1164
120 changed files with 15382 additions and 0 deletions
|
|
@ -0,0 +1,166 @@
|
|||
/**
|
||||
* common base class for the map-filters
|
||||
*
|
||||
* @author ab
|
||||
*/
|
||||
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 java.io.IOException;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.HashMap;
|
||||
|
||||
public abstract class MapCreatorBase implements WayListener, NodeListener, RelationListener
|
||||
{
|
||||
private DataOutputStream[] tileOutStreams;
|
||||
protected File outTileDir;
|
||||
|
||||
protected HashMap<String,String> tags;
|
||||
|
||||
public void putTag( String key, String value )
|
||||
{
|
||||
if ( tags == null ) tags = new HashMap<String,String>();
|
||||
tags.put( key, value );
|
||||
}
|
||||
|
||||
public String getTag( String key )
|
||||
{
|
||||
return tags == null ? null : tags.get( key );
|
||||
}
|
||||
|
||||
public HashMap<String,String> getTagsOrNull()
|
||||
{
|
||||
return tags;
|
||||
}
|
||||
|
||||
public void setTags( HashMap<String,String> tags )
|
||||
{
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
protected static long readId( DataInputStream is) throws IOException
|
||||
{
|
||||
int offset = is.readByte();
|
||||
if ( offset == 32 ) return -1;
|
||||
long i = is.readInt();
|
||||
i = i << 5;
|
||||
return i | offset;
|
||||
}
|
||||
|
||||
protected static void writeId( DataOutputStream o, long id ) throws IOException
|
||||
{
|
||||
if ( id == -1 )
|
||||
{
|
||||
o.writeByte( 32 );
|
||||
return;
|
||||
}
|
||||
int offset = (int)( id & 0x1f );
|
||||
int i = (int)( id >> 5 );
|
||||
o.writeByte( offset );
|
||||
o.writeInt( i );
|
||||
}
|
||||
|
||||
|
||||
protected static File[] sortBySizeAsc( File[] files )
|
||||
{
|
||||
int n = files.length;
|
||||
long[] sizes = new long[n];
|
||||
File[] sorted = new File[n];
|
||||
for( int i=0; i<n; i++ ) sizes[i] = files[i].length();
|
||||
for(int nf=0; nf<n; nf++)
|
||||
{
|
||||
int idx = -1;
|
||||
long min = -1;
|
||||
for( int i=0; i<n; i++ )
|
||||
{
|
||||
if ( sizes[i] != -1 && ( idx == -1 || sizes[i] < min ) )
|
||||
{
|
||||
min = sizes[i];
|
||||
idx = i;
|
||||
}
|
||||
}
|
||||
sizes[idx] = -1;
|
||||
sorted[nf] = files[idx];
|
||||
}
|
||||
return sorted;
|
||||
}
|
||||
|
||||
protected File fileFromTemplate( File template, File dir, String suffix )
|
||||
{
|
||||
String filename = template.getName();
|
||||
filename = filename.substring( 0, filename.length() - 3 ) + suffix;
|
||||
return new File( dir, filename );
|
||||
}
|
||||
|
||||
protected DataInputStream createInStream( File inFile ) throws IOException
|
||||
{
|
||||
return new DataInputStream( new BufferedInputStream ( new FileInputStream( inFile ) ) );
|
||||
}
|
||||
|
||||
protected DataOutputStream createOutStream( File outFile ) throws IOException
|
||||
{
|
||||
return new DataOutputStream( new BufferedOutputStream( new FileOutputStream( outFile ) ) );
|
||||
}
|
||||
|
||||
protected DataOutputStream getOutStreamForTile( int tileIndex ) throws Exception
|
||||
{
|
||||
if ( tileOutStreams == null )
|
||||
{
|
||||
tileOutStreams = new DataOutputStream[64];
|
||||
}
|
||||
|
||||
if ( tileOutStreams[tileIndex] == null )
|
||||
{
|
||||
tileOutStreams[tileIndex] = createOutStream( new File( outTileDir, getNameForTile( tileIndex ) ) );
|
||||
}
|
||||
return tileOutStreams[tileIndex];
|
||||
}
|
||||
|
||||
protected String getNameForTile( int tileIndex )
|
||||
{
|
||||
throw new IllegalArgumentException( "getNameForTile not implemented" );
|
||||
}
|
||||
|
||||
protected void closeTileOutStreams() throws Exception
|
||||
{
|
||||
if ( tileOutStreams == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
for( int tileIndex=0; tileIndex<tileOutStreams.length; tileIndex++ )
|
||||
{
|
||||
if ( tileOutStreams[tileIndex] != null ) tileOutStreams[tileIndex].close();
|
||||
tileOutStreams[tileIndex] = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// interface dummys
|
||||
|
||||
@Override
|
||||
public void nodeFileStart( File nodefile ) throws Exception {}
|
||||
|
||||
@Override
|
||||
public void nextNode( NodeData n ) throws Exception {}
|
||||
|
||||
@Override
|
||||
public void nodeFileEnd( File nodefile ) throws Exception {}
|
||||
|
||||
@Override
|
||||
public void wayFileStart( File wayfile ) throws Exception {}
|
||||
|
||||
@Override
|
||||
public void nextWay( WayData data ) throws Exception {}
|
||||
|
||||
@Override
|
||||
public void wayFileEnd( File wayfile ) throws Exception {}
|
||||
|
||||
@Override
|
||||
public void nextRelation( RelationData data ) throws Exception {}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
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.util.HashMap;
|
||||
|
||||
/**
|
||||
* NodeCutter does 1 step in map-processing:
|
||||
*
|
||||
* - cuts the 45*30 node tiles into 5*5 pieces
|
||||
*
|
||||
* @author ab
|
||||
*/
|
||||
public class NodeCutter extends MapCreatorBase
|
||||
{
|
||||
private int lonoffset;
|
||||
private int latoffset;
|
||||
|
||||
public static void main(String[] args) throws Exception
|
||||
{
|
||||
System.out.println("*** NodeCutter: Cut big node-tiles into 5x5 tiles");
|
||||
if (args.length != 2)
|
||||
{
|
||||
System.out.println("usage: java NodeCutter <node-tiles-in> <node-tiles-out>" );
|
||||
return;
|
||||
}
|
||||
new NodeCutter().process( new File( args[0] ), new File( args[1] ) );
|
||||
}
|
||||
|
||||
public void process( File nodeTilesIn, File nodeTilesOut ) throws Exception
|
||||
{
|
||||
this.outTileDir = nodeTilesOut;
|
||||
|
||||
new NodeIterator( this, true ).processDir( nodeTilesIn, ".tlf" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nodeFileStart( File nodefile ) throws Exception
|
||||
{
|
||||
lonoffset = -1;
|
||||
latoffset = -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextNode( NodeData n ) throws Exception
|
||||
{
|
||||
n.writeTo( getOutStreamForTile( getTileIndex( n.ilon, n.ilat ) ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nodeFileEnd( File nodeFile ) throws Exception
|
||||
{
|
||||
closeTileOutStreams();
|
||||
}
|
||||
|
||||
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 + ".n5d";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
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.util.HashMap;
|
||||
|
||||
import btools.util.*;
|
||||
|
||||
/**
|
||||
* Container for node data on the preprocessor level
|
||||
*
|
||||
* @author ab
|
||||
*/
|
||||
public class NodeData extends MapCreatorBase
|
||||
{
|
||||
public long nid;
|
||||
public int ilon;
|
||||
public int ilat;
|
||||
public long description;
|
||||
public short selev = Short.MIN_VALUE;
|
||||
|
||||
public NodeData( long id, double lon, double lat )
|
||||
{
|
||||
nid = id;
|
||||
ilat = (int)( ( lat + 90. )*1000000. + 0.5);
|
||||
ilon = (int)( ( lon + 180. )*1000000. + 0.5);
|
||||
}
|
||||
|
||||
public NodeData( DataInputStream dis ) throws Exception
|
||||
{
|
||||
nid = readId( dis );
|
||||
ilon = dis.readInt();
|
||||
ilat = dis.readInt();
|
||||
int mode = dis.readByte();
|
||||
if ( ( mode & 1 ) != 0 ) description = dis.readLong();
|
||||
if ( ( mode & 2 ) != 0 ) selev = dis.readShort();
|
||||
}
|
||||
|
||||
public void writeTo( DataOutputStream dos ) throws Exception
|
||||
{
|
||||
writeId( dos, nid );
|
||||
dos.writeInt( ilon );
|
||||
dos.writeInt( ilat );
|
||||
int mode = ( description == 0L ? 0 : 1 ) | ( selev == Short.MIN_VALUE ? 0 : 2 );
|
||||
dos.writeByte( (byte)mode );
|
||||
if ( ( mode & 1 ) != 0 ) dos.writeLong( description );
|
||||
if ( ( mode & 2 ) != 0 ) dos.writeShort( selev );
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
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.util.HashMap;
|
||||
|
||||
import btools.util.*;
|
||||
|
||||
/**
|
||||
* NodeFilter does 1 step in map-processing:
|
||||
*
|
||||
* - filters out unused nodes according to the way file
|
||||
*
|
||||
* @author ab
|
||||
*/
|
||||
public class NodeFilter extends MapCreatorBase
|
||||
{
|
||||
private DataOutputStream nodesOutStream;
|
||||
private File nodeTilesOut;
|
||||
protected DenseLongMap nodebitmap;
|
||||
|
||||
public static void main(String[] args) throws Exception
|
||||
{
|
||||
System.out.println("*** NodeFilter: Filter way related nodes");
|
||||
if (args.length != 3)
|
||||
{
|
||||
System.out.println("usage: java NodeFilter <node-tiles-in> <way-file-in> <node-tiles-out>" );
|
||||
return;
|
||||
}
|
||||
|
||||
new NodeFilter().process( new File( args[0] ), new File( args[1] ), new File( args[2] ) );
|
||||
}
|
||||
|
||||
public void process( File nodeTilesIn, File wayFileIn, File nodeTilesOut ) throws Exception
|
||||
{
|
||||
this.nodeTilesOut = nodeTilesOut;
|
||||
|
||||
// read the wayfile into a bitmap of used nodes
|
||||
nodebitmap = Boolean.getBoolean( "useDenseMaps" ) ? new DenseLongMap( 1 ) : new TinyDenseLongMap();
|
||||
new WayIterator( this, false ).processFile( wayFileIn );
|
||||
|
||||
// finally filter all node files
|
||||
new NodeIterator( this, true ).processDir( nodeTilesIn, ".tls" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextWay( WayData data ) throws Exception
|
||||
{
|
||||
int nnodes = data.nodes.size();
|
||||
for (int i=0; i<nnodes; i++ )
|
||||
{
|
||||
nodebitmap.put( data.nodes.get(i), 0 );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nodeFileStart( File nodefile ) throws Exception
|
||||
{
|
||||
String filename = nodefile.getName();
|
||||
filename = filename.substring( 0, filename.length() - 3 ) + "tlf";
|
||||
File outfile = new File( nodeTilesOut, filename );
|
||||
nodesOutStream = new DataOutputStream( new BufferedOutputStream ( new FileOutputStream( outfile ) ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextNode( NodeData n ) throws Exception
|
||||
{
|
||||
// check if node passes bitmap
|
||||
if ( nodebitmap.getInt( n.nid ) == 0 ) // 0 -> bit set, -1 -> unset
|
||||
{
|
||||
n.writeTo( nodesOutStream );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nodeFileEnd( File nodeFile ) throws Exception
|
||||
{
|
||||
nodesOutStream.close();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
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.util.HashMap;
|
||||
|
||||
import btools.util.*;
|
||||
|
||||
/**
|
||||
* Iterate over a singe nodefile or a directory
|
||||
* of nodetiles and feed the nodes to the callback listener
|
||||
*
|
||||
* @author ab
|
||||
*/
|
||||
public class NodeIterator extends MapCreatorBase
|
||||
{
|
||||
private NodeListener listener;
|
||||
private boolean delete;
|
||||
|
||||
public NodeIterator( NodeListener nodeListener, boolean deleteAfterReading )
|
||||
{
|
||||
listener = nodeListener;
|
||||
delete = deleteAfterReading;
|
||||
}
|
||||
|
||||
public void processDir( File indir, String inSuffix ) throws Exception
|
||||
{
|
||||
if ( !indir.isDirectory() )
|
||||
{
|
||||
throw new IllegalArgumentException( "not a directory: " + indir );
|
||||
}
|
||||
|
||||
File[] af = sortBySizeAsc( indir.listFiles() );
|
||||
for( int i=0; i<af.length; i++ )
|
||||
{
|
||||
File nodefile = af[i];
|
||||
if ( nodefile.getName().endsWith( inSuffix ) )
|
||||
{
|
||||
processFile( nodefile );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void processFile(File nodefile) throws Exception
|
||||
{
|
||||
System.out.println( "*** NodeIterator reading: " + nodefile );
|
||||
|
||||
listener.nodeFileStart( nodefile );
|
||||
|
||||
DataInputStream di = new DataInputStream( new BufferedInputStream ( new FileInputStream( nodefile ) ) );
|
||||
try
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
NodeData n = new NodeData( di );
|
||||
listener.nextNode( n );
|
||||
}
|
||||
}
|
||||
catch( EOFException eof )
|
||||
{
|
||||
di.close();
|
||||
}
|
||||
listener.nodeFileEnd( nodefile );
|
||||
if ( delete && "true".equals( System.getProperty( "deletetmpfiles" ) ))
|
||||
{
|
||||
nodefile.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package btools.mapcreator;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Callbacklistener for NodeIterator
|
||||
*
|
||||
* @author ab
|
||||
*/
|
||||
public interface NodeListener
|
||||
{
|
||||
void nodeFileStart( File nodefile ) throws Exception;
|
||||
|
||||
void nextNode( NodeData data ) throws Exception;
|
||||
|
||||
void nodeFileEnd( File nodefile ) throws Exception;
|
||||
}
|
||||
|
|
@ -0,0 +1,205 @@
|
|||
/**
|
||||
* 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.BufferedReader;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
import btools.expressions.BExpressionContext;
|
||||
|
||||
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;
|
||||
|
||||
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 != 4 && args.length != 5)
|
||||
{
|
||||
System.out.println("usage: bzip2 -dc <map> | java OsmCutter <lookup-file> <out-tile-dir> <out-way-file> <out-rel-file>");
|
||||
System.out.println("or : java OsmCutter <lookup-file> <out-tile-dir> <out-way-file> <out-rel-file> <inputfile>");
|
||||
return;
|
||||
}
|
||||
|
||||
new OsmCutter().process(
|
||||
new File( args[0] )
|
||||
, new File( args[1] )
|
||||
, new File( args[2] )
|
||||
, new File( args[3] )
|
||||
, args.length > 4 ? new File( args[4] ) : null );
|
||||
}
|
||||
|
||||
private BExpressionContext _expctxWay;
|
||||
private BExpressionContext _expctxNode;
|
||||
|
||||
public void process (File lookupFile, File outTileDir, File wayFile, File relFile, File mapFile) throws Exception
|
||||
{
|
||||
if ( !lookupFile.exists() )
|
||||
{
|
||||
throw new IllegalArgumentException( "lookup-file: " + lookupFile + " does not exist" );
|
||||
}
|
||||
|
||||
_expctxWay = new BExpressionContext("way");
|
||||
_expctxWay.readMetaData( lookupFile );
|
||||
|
||||
_expctxNode = new BExpressionContext("node");
|
||||
_expctxNode.readMetaData( lookupFile );
|
||||
|
||||
this.outTileDir = outTileDir;
|
||||
if ( !outTileDir.isDirectory() ) throw new RuntimeException( "out tile directory " + outTileDir + " does not exist" );
|
||||
|
||||
wayDos = new DataOutputStream( new BufferedOutputStream( new FileOutputStream( wayFile ) ) );
|
||||
cyclewayDos = new DataOutputStream( new BufferedOutputStream( new FileOutputStream( relFile ) ) );
|
||||
|
||||
// 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();
|
||||
wayDos.close();
|
||||
cyclewayDos.close();
|
||||
|
||||
/* System.out.println( "-------- way-statistics -------- " );
|
||||
_expctxWay.dumpStatistics();
|
||||
System.out.println( "-------- node-statistics -------- " );
|
||||
_expctxNode.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;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void nextNode( NodeData n ) throws Exception
|
||||
{
|
||||
nodesParsed++;
|
||||
checkStats();
|
||||
|
||||
if ( n.getTagsOrNull() != null )
|
||||
{
|
||||
int[] lookupData = _expctxNode.createNewLookupData();
|
||||
for( String key : n.getTagsOrNull().keySet() )
|
||||
{
|
||||
String value = n.getTag( key );
|
||||
_expctxNode.addLookupValue( key, value, lookupData );
|
||||
}
|
||||
n.description = _expctxNode.encode(lookupData);
|
||||
}
|
||||
// write node to file
|
||||
int tileIndex = getTileIndex( n.ilon, n.ilat );
|
||||
if ( tileIndex >= 0 )
|
||||
{
|
||||
DataOutputStream dos = getOutStreamForTile( tileIndex );
|
||||
n.writeTo( dos );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void nextWay( WayData w ) throws Exception
|
||||
{
|
||||
waysParsed++;
|
||||
checkStats();
|
||||
|
||||
// filter out non-highway ways
|
||||
if ( w.getTag( "highway" ) == null )
|
||||
{
|
||||
// ... but eventually fake a ferry tag
|
||||
if ( "ferry".equals( w.getTag( "route" ) ) )
|
||||
{
|
||||
w.putTag( "highway", "ferry" );
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// encode tags
|
||||
if ( w.getTagsOrNull() != null )
|
||||
{
|
||||
int[] lookupData = _expctxWay.createNewLookupData();
|
||||
for( String key : w.getTagsOrNull().keySet() )
|
||||
{
|
||||
String value = w.getTag( key );
|
||||
_expctxWay.addLookupValue( key, value, lookupData );
|
||||
}
|
||||
w.description = _expctxWay.encode(lookupData);
|
||||
}
|
||||
|
||||
w.writeTo( wayDos );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextRelation( RelationData r ) throws Exception
|
||||
{
|
||||
relsParsed++;
|
||||
checkStats();
|
||||
|
||||
// filter out non-cycle relations
|
||||
if ( ! "bicycle".equals( r.getTag( "route" ) ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for ( int i=0; i<r.ways.size();i++ )
|
||||
{
|
||||
long wid = r.ways.get(i);
|
||||
writeId( cyclewayDos, wid );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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 + ".tls";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* Container for link between two Osm nodes (pre-pocessor version)
|
||||
*
|
||||
* @author ab
|
||||
*/
|
||||
package btools.mapcreator;
|
||||
|
||||
|
||||
public final class OsmLinkP
|
||||
{
|
||||
/**
|
||||
* The description bitmap is mainly the way description
|
||||
* used to calculate the costfactor
|
||||
*/
|
||||
public long descriptionBitmap;
|
||||
|
||||
/**
|
||||
* The target is either the next link or the target node
|
||||
*/
|
||||
public OsmNodeP targetNode;
|
||||
|
||||
public OsmLinkP next;
|
||||
|
||||
|
||||
public boolean counterLinkWritten( )
|
||||
{
|
||||
return descriptionBitmap == 0L;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,243 @@
|
|||
/**
|
||||
* Container for an osm node (pre-pocessor version)
|
||||
*
|
||||
* @author ab
|
||||
*/
|
||||
package btools.mapcreator;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class OsmNodeP implements Comparable<OsmNodeP>
|
||||
{
|
||||
public static final int EXTERNAL_BITMASK = 0x80;
|
||||
public static final int FIRSTFORWAY_BITMASK = 0x40;
|
||||
public static final int TRANSFERNODE_BITMASK = 0x20;
|
||||
public static final int WRITEDESC_BITMASK = 0x10;
|
||||
public static final int SKIPDETAILS_BITMASK = 0x08;
|
||||
public static final int NODEDESC_BITMASK = 0x04;
|
||||
|
||||
/**
|
||||
* The latitude
|
||||
*/
|
||||
public int ilat;
|
||||
|
||||
/**
|
||||
* The longitude
|
||||
*/
|
||||
public int ilon;
|
||||
|
||||
|
||||
/**
|
||||
* The links to other nodes
|
||||
*/
|
||||
public OsmLinkP firstlink = null;
|
||||
|
||||
|
||||
/**
|
||||
* The elevation
|
||||
*/
|
||||
public short selev;
|
||||
|
||||
public boolean isBorder = false;
|
||||
|
||||
public byte wayAndBits = -1; // use for bridge/tunnel logic
|
||||
|
||||
|
||||
// interface OsmPos
|
||||
public int getILat()
|
||||
{
|
||||
return ilat;
|
||||
}
|
||||
|
||||
public int getILon()
|
||||
{
|
||||
return ilon;
|
||||
}
|
||||
|
||||
public short getSElev()
|
||||
{
|
||||
// if all bridge or all tunnel, elevation=no-data
|
||||
return (wayAndBits & 24) == 0 ? selev : Short.MIN_VALUE;
|
||||
}
|
||||
|
||||
public double getElev()
|
||||
{
|
||||
return selev / 4.;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void addLink( OsmLinkP link )
|
||||
{
|
||||
if ( firstlink != null ) link.next = firstlink;
|
||||
firstlink = link;
|
||||
}
|
||||
|
||||
public long getNodeDecsription()
|
||||
{
|
||||
return 0L;
|
||||
}
|
||||
|
||||
public void writeNodeData( DataOutputStream os ) throws IOException
|
||||
{
|
||||
int lonIdx = ilon/62500;
|
||||
int latIdx = ilat/62500;
|
||||
|
||||
// buffer the body to first calc size
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream( );
|
||||
DataOutputStream os2 = new DataOutputStream( bos );
|
||||
|
||||
os2.writeShort( getSElev() );
|
||||
|
||||
int nlinks = 0;
|
||||
|
||||
// hack: write node-desc as link tag (copy cycleway-bits)
|
||||
long nodeDescription = getNodeDecsription();
|
||||
|
||||
for( OsmLinkP link0 = firstlink; link0 != null; link0 = link0.next )
|
||||
{
|
||||
nlinks++;
|
||||
OsmLinkP link = link0;
|
||||
OsmNodeP origin = this;
|
||||
int skipDetailBit = link0.counterLinkWritten() ? SKIPDETAILS_BITMASK : 0;
|
||||
|
||||
// first pass just to see if that link is consistent
|
||||
while( link != null )
|
||||
{
|
||||
OsmNodeP target = link.targetNode;
|
||||
if ( !target.isTransferNode() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
// next link is the one (of two), does does'nt point back
|
||||
for( link = target.firstlink; link != null; link = link.next )
|
||||
{
|
||||
if ( link.targetNode != origin ) break;
|
||||
}
|
||||
origin = target;
|
||||
}
|
||||
if ( link == null ) continue; // dead end
|
||||
|
||||
if ( skipDetailBit == 0)
|
||||
{
|
||||
link = link0;
|
||||
}
|
||||
origin = this;
|
||||
long lastDescription = 0;
|
||||
while( link != null )
|
||||
{
|
||||
OsmNodeP target = link.targetNode;
|
||||
int tranferbit = target.isTransferNode() ? TRANSFERNODE_BITMASK : 0;
|
||||
int writedescbit = link.descriptionBitmap != lastDescription ? WRITEDESC_BITMASK : 0;
|
||||
int nodedescbit = nodeDescription != 0L ? NODEDESC_BITMASK : 0;
|
||||
|
||||
if ( skipDetailBit != 0 )
|
||||
{
|
||||
writedescbit = 0;
|
||||
}
|
||||
int targetLonIdx = target.ilon/62500;
|
||||
int targetLatIdx = target.ilat/62500;
|
||||
|
||||
if ( targetLonIdx == lonIdx && targetLatIdx == latIdx )
|
||||
{
|
||||
// reduced position for internal target
|
||||
os2.writeByte( tranferbit | writedescbit | nodedescbit | skipDetailBit );
|
||||
os2.writeShort( (short)(target.ilon - lonIdx*62500 - 31250) );
|
||||
os2.writeShort( (short)(target.ilat - latIdx*62500 - 31250) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// full position for external target
|
||||
os2.writeByte( tranferbit | writedescbit | nodedescbit | skipDetailBit | EXTERNAL_BITMASK );
|
||||
os2.writeInt( target.ilon );
|
||||
os2.writeInt( target.ilat );
|
||||
}
|
||||
if ( writedescbit != 0 )
|
||||
{
|
||||
os2.writeLong( link.descriptionBitmap );
|
||||
}
|
||||
if ( nodedescbit != 0 )
|
||||
{
|
||||
os2.writeLong( nodeDescription );
|
||||
nodeDescription = 0L;
|
||||
}
|
||||
lastDescription = link.descriptionBitmap;
|
||||
|
||||
if ( tranferbit == 0)
|
||||
{
|
||||
target.markLinkWritten( origin );
|
||||
break;
|
||||
}
|
||||
os2.writeShort( target.getSElev() );
|
||||
// next link is the one (of two), does does'nt point back
|
||||
for( link = target.firstlink; link != null; link = link.next )
|
||||
{
|
||||
if ( link.targetNode != origin ) break;
|
||||
}
|
||||
if ( link == null ) throw new RuntimeException( "follow-up link not found for transfer-node!" );
|
||||
origin = target;
|
||||
}
|
||||
}
|
||||
|
||||
// calculate the body size
|
||||
int bodySize = bos.size();
|
||||
|
||||
os.writeShort( (short)(ilon - lonIdx*62500 - 31250) );
|
||||
os.writeShort( (short)(ilat - latIdx*62500 - 31250) );
|
||||
os.writeInt( bodySize );
|
||||
bos.writeTo( os );
|
||||
}
|
||||
|
||||
public String toString2()
|
||||
{
|
||||
return (ilon-180000000) + "_" + (ilat-90000000) + "_" + (selev/4);
|
||||
}
|
||||
|
||||
public long getIdFromPos()
|
||||
{
|
||||
return ((long)ilon)<<32 | ilat;
|
||||
}
|
||||
|
||||
public boolean isTransferNode()
|
||||
{
|
||||
return (!isBorder) && _linkCnt() == 2;
|
||||
}
|
||||
|
||||
private int _linkCnt()
|
||||
{
|
||||
int cnt = 0;
|
||||
|
||||
for( OsmLinkP link = firstlink; link != null; link = link.next )
|
||||
{
|
||||
cnt++;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
// mark the link to the given node as written,
|
||||
// don't want to write the counter-direction
|
||||
// in full details
|
||||
public void markLinkWritten( OsmNodeP t )
|
||||
{
|
||||
for( OsmLinkP link = firstlink; link != null; link = link.next )
|
||||
{
|
||||
if ( link.targetNode == t) link.descriptionBitmap = 0L;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two OsmNodes for position ordering.
|
||||
*
|
||||
* @return -1,0,1 depending an comparson result
|
||||
*/
|
||||
public int compareTo( OsmNodeP n )
|
||||
{
|
||||
long id1 = getIdFromPos();
|
||||
long id2 = n.getIdFromPos();
|
||||
if ( id1 < id2 ) return -1;
|
||||
if ( id1 > id2 ) return 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
* Container for an osm node with tags (pre-pocessor version)
|
||||
*
|
||||
* @author ab
|
||||
*/
|
||||
package btools.mapcreator;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class OsmNodePT extends OsmNodeP
|
||||
{
|
||||
public long descriptionBits;
|
||||
|
||||
public byte wayOrBits = 0; // used to propagate bike networks to nodes
|
||||
|
||||
public OsmNodePT()
|
||||
{
|
||||
}
|
||||
|
||||
public OsmNodePT( long descriptionBits )
|
||||
{
|
||||
this.descriptionBits = descriptionBits;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getNodeDecsription()
|
||||
{
|
||||
return descriptionBits | (long)( (wayOrBits & 6) >> 1 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTransferNode()
|
||||
{
|
||||
return false; // always have descriptionBits so never transfernode
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,240 @@
|
|||
package btools.mapcreator;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
/**
|
||||
* Parser for OSM data
|
||||
*
|
||||
* @author ab
|
||||
*/
|
||||
public class OsmParser extends MapCreatorBase
|
||||
{
|
||||
private BufferedReader _br;
|
||||
|
||||
private NodeListener nListener;
|
||||
private WayListener wListener;
|
||||
private RelationListener rListener;
|
||||
|
||||
public void readMap( File mapFile,
|
||||
NodeListener nListener,
|
||||
WayListener wListener,
|
||||
RelationListener rListener ) throws Exception
|
||||
{
|
||||
|
||||
this.nListener = nListener;
|
||||
this.wListener = wListener;
|
||||
this.rListener = rListener;
|
||||
|
||||
if ( mapFile == null )
|
||||
{
|
||||
_br = new BufferedReader(new InputStreamReader(System.in));
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( mapFile.getName().endsWith( ".gz" ) )
|
||||
{
|
||||
_br = new BufferedReader(new InputStreamReader( new GZIPInputStream( new FileInputStream( mapFile ) ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
_br = new BufferedReader(new InputStreamReader( new FileInputStream( mapFile ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
for(;;)
|
||||
{
|
||||
String line = _br.readLine();
|
||||
if ( line == null ) break;
|
||||
|
||||
if ( checkNode( line ) ) continue;
|
||||
if ( checkWay( line ) ) continue;
|
||||
if ( checkRelation( line ) ) continue;
|
||||
if ( checkChangeset( line ) ) continue;
|
||||
}
|
||||
|
||||
if ( mapFile != null )
|
||||
{
|
||||
_br.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean checkNode( String line ) throws Exception
|
||||
{
|
||||
int idx0 = line.indexOf( "<node id=\"" );
|
||||
if ( idx0 < 0 ) return false;
|
||||
idx0 += 10;
|
||||
int idx1 = line.indexOf( '"', idx0 );
|
||||
|
||||
long nodeId = Long.parseLong( line.substring( idx0, idx1 ) );
|
||||
|
||||
int idx2 = line.indexOf( " lat=\"" );
|
||||
if ( idx2 < 0 ) return false;
|
||||
idx2 += 6;
|
||||
int idx3 = line.indexOf( '"', idx2 );
|
||||
double lat = Double.parseDouble( line.substring( idx2, idx3 ) );
|
||||
int idx4 = line.indexOf( " lon=\"" );
|
||||
if ( idx4 < 0 ) return false;
|
||||
idx4 += 6;
|
||||
int idx5 = line.indexOf( '"', idx4 );
|
||||
double lon = Double.parseDouble( line.substring( idx4, idx5 ) );
|
||||
|
||||
NodeData n = new NodeData( nodeId, lon, lat );
|
||||
|
||||
if ( !line.endsWith( "/>" ) )
|
||||
{
|
||||
// read additional tags
|
||||
for(;;)
|
||||
{
|
||||
String l2 = _br.readLine();
|
||||
if ( l2 == null ) return false;
|
||||
|
||||
int i2;
|
||||
if ( (i2 = l2.indexOf( "<tag k=\"" )) >= 0 )
|
||||
{ // property-tag
|
||||
i2 += 8;
|
||||
int ri2 = l2.indexOf( '"', i2 );
|
||||
String key = l2.substring( i2, ri2 );
|
||||
i2 = l2.indexOf( " v=\"", ri2 );
|
||||
if ( i2 >= 0 )
|
||||
{
|
||||
i2 += 4;
|
||||
int ri3 = l2.indexOf( '"', i2 );
|
||||
String value = l2.substring( i2, ri3 );
|
||||
|
||||
n.putTag( key, value );
|
||||
}
|
||||
}
|
||||
else if ( l2.indexOf( "</node>" ) >= 0 )
|
||||
{ // end-tag
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
nListener.nextNode( n );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private boolean checkWay( String line ) throws Exception
|
||||
{
|
||||
int idx0 = line.indexOf( "<way id=\"" );
|
||||
if ( idx0 < 0 ) return false;
|
||||
|
||||
idx0 += 9;
|
||||
int idx1 = line.indexOf( '"', idx0 );
|
||||
long id = Long.parseLong( line.substring( idx0, idx1 ) );
|
||||
|
||||
WayData w = new WayData( id );
|
||||
|
||||
// read the nodes
|
||||
for(;;)
|
||||
{
|
||||
String l2 = _br.readLine();
|
||||
if ( l2 == null ) return false;
|
||||
|
||||
int i2;
|
||||
if ( (i2 = l2.indexOf( "<nd ref=\"" )) >= 0 )
|
||||
{ // node reference
|
||||
i2 += 9;
|
||||
int ri2 = l2.indexOf( '"', i2 );
|
||||
long nid = Long.parseLong( l2.substring( i2, ri2 ) );
|
||||
w.nodes.add( nid );
|
||||
}
|
||||
else if ( (i2 = l2.indexOf( "<tag k=\"" )) >= 0 )
|
||||
{ // property-tag
|
||||
i2 += 8;
|
||||
int ri2 = l2.indexOf( '"', i2 );
|
||||
String key = l2.substring( i2, ri2 );
|
||||
i2 = l2.indexOf( " v=\"", ri2 );
|
||||
if ( i2 >= 0 )
|
||||
{
|
||||
i2 += 4;
|
||||
int ri3 = l2.indexOf( '"', i2 );
|
||||
String value = l2.substring( i2, ri3 );
|
||||
w.putTag( key, value );
|
||||
}
|
||||
}
|
||||
else if ( l2.indexOf( "</way>" ) >= 0 )
|
||||
{ // end-tag
|
||||
break;
|
||||
}
|
||||
}
|
||||
wListener.nextWay( w );
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean checkChangeset( String line ) throws Exception
|
||||
{
|
||||
int idx0 = line.indexOf( "<changeset id=\"" );
|
||||
if ( idx0 < 0 ) return false;
|
||||
|
||||
if ( !line.endsWith( "/>" ) )
|
||||
{
|
||||
int loopcheck = 0;
|
||||
for(;;)
|
||||
{
|
||||
String l2 = _br.readLine();
|
||||
if ( l2.indexOf("</changeset>") >= 0 || ++loopcheck > 10000 ) break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean checkRelation( String line ) throws Exception
|
||||
{
|
||||
int idx0 = line.indexOf( "<relation id=\"" );
|
||||
if ( idx0 < 0 ) return false;
|
||||
|
||||
idx0 += 14;
|
||||
int idx1 = line.indexOf( '"', idx0 );
|
||||
long rid = Long.parseLong( line.substring( idx0, idx1 ) );
|
||||
|
||||
RelationData r = new RelationData( rid );
|
||||
|
||||
// read the nodes
|
||||
for(;;)
|
||||
{
|
||||
String l2 = _br.readLine();
|
||||
if ( l2 == null ) return false;
|
||||
|
||||
int i2;
|
||||
if ( (i2 = l2.indexOf( "<member type=\"way\" ref=\"" )) >= 0 )
|
||||
{ // node reference
|
||||
i2 += 24;
|
||||
int ri2 = l2.indexOf( '"', i2 );
|
||||
long wid = Long.parseLong( l2.substring( i2, ri2 ) );
|
||||
r.ways.add( wid );
|
||||
}
|
||||
else if ( (i2 = l2.indexOf( "<tag k=\"" )) >= 0 )
|
||||
{ // property-tag
|
||||
i2 += 8;
|
||||
int ri2 = l2.indexOf( '"', i2 );
|
||||
String key = l2.substring( i2, ri2 );
|
||||
i2 = l2.indexOf( " v=\"", ri2 );
|
||||
if ( i2 >= 0 )
|
||||
{
|
||||
i2 += 4;
|
||||
int ri3 = l2.indexOf( '"', i2 );
|
||||
String value = l2.substring( i2, ri3 );
|
||||
r.putTag( key, value );
|
||||
}
|
||||
}
|
||||
else if ( l2.indexOf( "</relation>" ) >= 0 )
|
||||
{ // end-tag
|
||||
break;
|
||||
}
|
||||
}
|
||||
rListener.nextRelation( r );
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,203 @@
|
|||
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.util.HashMap;
|
||||
|
||||
import btools.util.CompactLongSet;
|
||||
import btools.util.CompactLongMap;
|
||||
import btools.util.FrozenLongSet;
|
||||
import btools.util.FrozenLongMap;
|
||||
|
||||
/**
|
||||
* PosUnifier does 3 steps in map-processing:
|
||||
*
|
||||
* - unify positions
|
||||
* - add srtm elevation data
|
||||
* - make a bordernodes file containing net data
|
||||
* from the bordernids-file just containing ids
|
||||
*
|
||||
* @author ab
|
||||
*/
|
||||
public class PosUnifier extends MapCreatorBase
|
||||
{
|
||||
private DataOutputStream nodesOutStream;
|
||||
private DataOutputStream borderNodesOut;
|
||||
private File nodeTilesOut;
|
||||
private CompactLongSet positionSet;
|
||||
|
||||
private HashMap<String,SrtmData> srtmmap ;
|
||||
private int lastStrmLonIdx;
|
||||
private int lastStrmLatIdx;
|
||||
private SrtmData lastSrtmData;
|
||||
private String srtmdir;
|
||||
|
||||
private int totalLatSteps = 0;
|
||||
private int totalLonSteps = 0;
|
||||
|
||||
private CompactLongSet borderNids;
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception
|
||||
{
|
||||
System.out.println("*** PosUnifier: Unify position values and enhance elevation");
|
||||
if (args.length != 5)
|
||||
{
|
||||
System.out.println("usage: java PosUnifier <node-tiles-in> <node-tiles-out> <bordernids-in> <bordernodes-out> <strm-data-dir>" );
|
||||
return;
|
||||
}
|
||||
new PosUnifier().process( new File( args[0] ), new File( args[1] ), new File( args[2] ), new File( args[3] ), args[4] );
|
||||
}
|
||||
|
||||
public void process( File nodeTilesIn, File nodeTilesOut, File bordernidsinfile, File bordernodesoutfile, String srtmdir ) throws Exception
|
||||
{
|
||||
this.nodeTilesOut = nodeTilesOut;
|
||||
this.srtmdir = srtmdir;
|
||||
|
||||
// read border nids set
|
||||
DataInputStream dis = createInStream( bordernidsinfile );
|
||||
borderNids = new CompactLongSet();
|
||||
try
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
long nid = readId( dis );
|
||||
if ( !borderNids.contains( nid ) ) borderNids.fastAdd( nid );
|
||||
}
|
||||
}
|
||||
catch( EOFException eof )
|
||||
{
|
||||
dis.close();
|
||||
}
|
||||
borderNids = new FrozenLongSet( borderNids );
|
||||
|
||||
// process all files
|
||||
borderNodesOut = createOutStream( bordernodesoutfile );
|
||||
new NodeIterator( this, true ).processDir( nodeTilesIn, ".n5d" );
|
||||
borderNodesOut.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nodeFileStart( File nodefile ) throws Exception
|
||||
{
|
||||
resetSrtm();
|
||||
|
||||
nodesOutStream = createOutStream( fileFromTemplate( nodefile, nodeTilesOut, "u5d" ) );
|
||||
|
||||
positionSet = new CompactLongSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextNode( NodeData n ) throws Exception
|
||||
{
|
||||
SrtmData srtm = srtmForNode( n.ilon, n.ilat );
|
||||
n.selev = srtm == null ? Short.MIN_VALUE : srtm.getElevation( n.ilon, n.ilat);
|
||||
|
||||
findUniquePos( n );
|
||||
|
||||
n.writeTo( nodesOutStream );
|
||||
if ( borderNids.contains( n.nid ) )
|
||||
{
|
||||
n.writeTo( borderNodesOut );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nodeFileEnd( File nodeFile ) throws Exception
|
||||
{
|
||||
nodesOutStream.close();
|
||||
}
|
||||
|
||||
private void findUniquePos( NodeData n )
|
||||
{
|
||||
// fix the position for uniqueness
|
||||
int lonmod = n.ilon % 1000000;
|
||||
int londelta = lonmod < 500000 ? 1 : -1;
|
||||
int latmod = n.ilat % 1000000;
|
||||
int latdelta = latmod < 500000 ? 1 : -1;
|
||||
for(int latsteps = 0; latsteps < 100; latsteps++)
|
||||
{
|
||||
for(int lonsteps = 0; lonsteps <= latsteps; lonsteps++)
|
||||
{
|
||||
int lon = n.ilon + lonsteps*londelta;
|
||||
int lat = n.ilat + latsteps*latdelta;
|
||||
long pid = ((long)lon)<<32 | lat; // id from position
|
||||
if ( !positionSet.contains( pid ) )
|
||||
{
|
||||
totalLonSteps += lonsteps;
|
||||
totalLatSteps += latsteps;
|
||||
positionSet.fastAdd( pid );
|
||||
n.ilon = lon;
|
||||
n.ilat = lat;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println( "*** WARNING: cannot unify position for: " + n.ilon + " " + n.ilat );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get the srtm data set for a position
|
||||
* srtm coords are srtm_<srtmLon>_<srtmLat>
|
||||
* where srtmLon = 180 + lon, srtmLat = 60 - lat
|
||||
*/
|
||||
private SrtmData srtmForNode( int ilon, int ilat ) throws Exception
|
||||
{
|
||||
int srtmLonIdx = (ilon+5000000)/5000000;
|
||||
int srtmLatIdx = (154999999-ilat)/5000000;
|
||||
|
||||
if ( srtmLatIdx < 1 || srtmLatIdx > 24 || srtmLonIdx < 1 || srtmLonIdx > 72 )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if ( srtmLonIdx == lastStrmLonIdx && srtmLatIdx == lastStrmLatIdx )
|
||||
{
|
||||
return lastSrtmData;
|
||||
}
|
||||
lastStrmLonIdx = srtmLonIdx;
|
||||
lastStrmLatIdx = srtmLatIdx;
|
||||
|
||||
StringBuilder sb = new StringBuilder( 16 );
|
||||
sb.append( "srtm_" );
|
||||
sb.append( (char)('0' + srtmLonIdx/10 ) ).append( (char)('0' + srtmLonIdx%10 ) ).append( '_' );
|
||||
sb.append( (char)('0' + srtmLatIdx/10 ) ).append( (char)('0' + srtmLatIdx%10 ) ).append( ".zip" );
|
||||
String filename = sb.toString();
|
||||
|
||||
|
||||
lastSrtmData = srtmmap.get( filename );
|
||||
if ( lastSrtmData == null && !srtmmap.containsKey( filename ) )
|
||||
{
|
||||
File f = new File( new File( srtmdir ), filename );
|
||||
System.out.println( "reading: " + f + " ilon=" + ilon + " ilat=" + ilat );
|
||||
if ( f.exists() )
|
||||
{
|
||||
try
|
||||
{
|
||||
lastSrtmData = new SrtmData( f );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
System.out.println( "**** ERROR reading " + f + " ****" );
|
||||
}
|
||||
}
|
||||
srtmmap.put( filename, lastSrtmData );
|
||||
}
|
||||
return lastSrtmData;
|
||||
}
|
||||
|
||||
private void resetSrtm()
|
||||
{
|
||||
srtmmap = new HashMap<String,SrtmData>();
|
||||
lastStrmLonIdx = -1;
|
||||
lastStrmLatIdx = -1;
|
||||
lastSrtmData = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
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.util.HashMap;
|
||||
|
||||
import btools.util.*;
|
||||
|
||||
/**
|
||||
* Container for relation data on the preprocessor level
|
||||
*
|
||||
* @author ab
|
||||
*/
|
||||
public class RelationData extends MapCreatorBase
|
||||
{
|
||||
public long rid;
|
||||
public long description;
|
||||
public LongList ways;
|
||||
|
||||
public RelationData( long id )
|
||||
{
|
||||
rid = id;
|
||||
ways = new LongList( 16 );
|
||||
}
|
||||
|
||||
public RelationData( long id, LongList ways )
|
||||
{
|
||||
rid = id;
|
||||
this.ways = ways;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package btools.mapcreator;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Callbacklistener for Relations
|
||||
*
|
||||
* @author ab
|
||||
*/
|
||||
public interface RelationListener
|
||||
{
|
||||
void nextRelation( RelationData data ) throws Exception;
|
||||
}
|
||||
|
|
@ -0,0 +1,174 @@
|
|||
/**
|
||||
* This is a wrapper for a 5*5 degree srtm file in ascii/zip-format
|
||||
*
|
||||
* - filter out unused nodes according to the way file
|
||||
* - enhance with SRTM elevation data
|
||||
* - split further in smaller (5*5 degree) tiles
|
||||
*
|
||||
* @author ab
|
||||
*/
|
||||
package btools.mapcreator;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
|
||||
public class SrtmData
|
||||
{
|
||||
public int ncols;
|
||||
public int nrows;
|
||||
public double xllcorner;
|
||||
public double yllcorner;
|
||||
public double cellsize;
|
||||
public int nodata_value;
|
||||
public short[] eval_array;
|
||||
|
||||
private double minlon;
|
||||
private double maxlon;
|
||||
private double minlat;
|
||||
private double maxlat;
|
||||
|
||||
public void init()
|
||||
{
|
||||
minlon = xllcorner;
|
||||
maxlon = minlon + cellsize*ncols;
|
||||
minlat = yllcorner;
|
||||
maxlat = minlat + cellsize*nrows;
|
||||
}
|
||||
|
||||
private boolean missingData = false;
|
||||
|
||||
public short getElevation( int ilon, int ilat )
|
||||
{
|
||||
double lon = ilon / 1000000. - 180.;
|
||||
double lat = ilat / 1000000. - 90.;
|
||||
|
||||
double dcol = (lon - minlon)/cellsize -0.5;
|
||||
double drow = (lat - minlat)/cellsize -0.5;
|
||||
int row = (int)drow;
|
||||
int col = (int)dcol;
|
||||
if ( col < 0 ) col = 0;
|
||||
if ( col >= ncols-1 ) col = ncols - 2;
|
||||
if ( row < 0 ) row = 0;
|
||||
if ( row >= nrows-1 ) row = nrows - 2;
|
||||
double wrow = drow-row;
|
||||
double wcol = dcol-col;
|
||||
missingData = false;
|
||||
double eval = (1.-wrow)*(1.-wcol)*get(row ,col )
|
||||
+ ( wrow)*(1.-wcol)*get(row+1,col )
|
||||
+ (1.-wrow)*( wcol)*get(row ,col+1)
|
||||
+ ( wrow)*( wcol)*get(row+1,col+1);
|
||||
return missingData ? Short.MIN_VALUE : (short)(eval);
|
||||
}
|
||||
|
||||
private short get( int r, int c )
|
||||
{
|
||||
short e = eval_array[r*ncols + c ];
|
||||
if ( e == Short.MIN_VALUE ) missingData = true;
|
||||
return e;
|
||||
}
|
||||
|
||||
public SrtmData( File file ) throws Exception
|
||||
{
|
||||
ZipInputStream zis = new ZipInputStream( new FileInputStream( file ) );
|
||||
try
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
ZipEntry ze = zis.getNextEntry();
|
||||
if ( ze.getName().endsWith( ".asc" ) )
|
||||
{
|
||||
readFromStream( zis );
|
||||
|
||||
/* // test
|
||||
int[] ca = new int[]{ 50477121, 8051915, // 181
|
||||
50477742, 8047408, // 154
|
||||
50477189, 8047308, // 159
|
||||
};
|
||||
for( int i=0; i<ca.length; i+=2 )
|
||||
{
|
||||
int lat=ca[i] + 90000000;
|
||||
int lon=ca[i+1] + 180000000;
|
||||
System.err.println( "lat=" + lat + " lon=" + lon + " elev=" + getElevation( lon, lat )/4. );
|
||||
}
|
||||
// end test
|
||||
*/
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
zis.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void readFromStream( InputStream is ) throws Exception
|
||||
{
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(is));
|
||||
int linenr = 0;
|
||||
for(;;)
|
||||
{
|
||||
linenr++;
|
||||
if ( linenr <= 6 )
|
||||
{
|
||||
String line = br.readLine();
|
||||
if ( linenr == 1 ) ncols = Integer.parseInt( line.substring(14) );
|
||||
else if ( linenr == 2 ) nrows = Integer.parseInt( line.substring(14) );
|
||||
else if ( linenr == 3 ) xllcorner = Double.parseDouble( line.substring(14) );
|
||||
else if ( linenr == 4 ) yllcorner = Double.parseDouble( line.substring(14) );
|
||||
else if ( linenr == 5 ) cellsize = Double.parseDouble( line.substring(14) );
|
||||
else if ( linenr == 6 )
|
||||
{
|
||||
nodata_value = Integer.parseInt( line.substring(14) );
|
||||
eval_array = new short[ncols * nrows];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int row = 0;
|
||||
int col = 0;
|
||||
int n = 0;
|
||||
boolean negative = false;
|
||||
for(;;)
|
||||
{
|
||||
int c = br.read();
|
||||
if ( c < 0 ) break;
|
||||
if ( c == ' ' )
|
||||
{
|
||||
if ( negative ) n = -n;
|
||||
short val = n == nodata_value ? Short.MIN_VALUE : (short)(n*4);
|
||||
if ( val < -1000 ) val = Short.MIN_VALUE;
|
||||
|
||||
eval_array[ (nrows-1-row)*ncols + col ] = val;
|
||||
if (++col == ncols )
|
||||
{
|
||||
col = 0;
|
||||
++row;
|
||||
}
|
||||
n = 0;
|
||||
negative = false;
|
||||
}
|
||||
else if ( c >= '0' && c <= '9' )
|
||||
{
|
||||
n = 10*n + (c-'0');
|
||||
}
|
||||
else if ( c == '-' )
|
||||
{
|
||||
negative = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
init();
|
||||
br.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
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.util.HashMap;
|
||||
|
||||
import btools.util.*;
|
||||
|
||||
/**
|
||||
* WayCutter does 2 step in map-processing:
|
||||
*
|
||||
* - cut the way file into 45*30 - pieces
|
||||
* - enrich ways with relation information
|
||||
*
|
||||
* @author ab
|
||||
*/
|
||||
public class WayCutter extends MapCreatorBase
|
||||
{
|
||||
private CompactLongSet cyclewayset;
|
||||
private DenseLongMap tileIndexMap;
|
||||
|
||||
public static void main(String[] args) throws Exception
|
||||
{
|
||||
System.out.println("*** WayCutter: Soft-Cut way-data into tiles");
|
||||
if (args.length != 4)
|
||||
{
|
||||
System.out.println("usage: java WayCutter <node-tiles-in> <way-file-in> <way-tiles-out> <relation-file>" );
|
||||
|
||||
return;
|
||||
}
|
||||
new WayCutter().process( new File( args[0] ), new File( args[1] ), new File( args[2] ), new File( args[3] ) );
|
||||
}
|
||||
|
||||
public void process( File nodeTilesIn, File wayFileIn, File wayTilesOut, File relationFileIn ) throws Exception
|
||||
{
|
||||
this.outTileDir = wayTilesOut;
|
||||
|
||||
// *** read the relation file into a set (currently cycleway processing only)
|
||||
cyclewayset = new CompactLongSet();
|
||||
DataInputStream dis = createInStream( relationFileIn );
|
||||
try
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
long wid = readId( dis );
|
||||
if ( !cyclewayset.contains( wid ) ) cyclewayset.add( wid );
|
||||
}
|
||||
}
|
||||
catch( EOFException eof )
|
||||
{
|
||||
dis.close();
|
||||
}
|
||||
System.out.println( "marked cycleways: " + cyclewayset.size() );
|
||||
|
||||
|
||||
// *** read all nodes into tileIndexMap
|
||||
tileIndexMap = Boolean.getBoolean( "useDenseMaps" ) ? new DenseLongMap( 6 ) : new TinyDenseLongMap();
|
||||
new NodeIterator( this, false ).processDir( nodeTilesIn, ".tlf" );
|
||||
|
||||
// *** finally process the way-file, cutting into pieces
|
||||
new WayIterator( this, true ).processFile( wayFileIn );
|
||||
closeTileOutStreams();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextNode( NodeData n ) throws Exception
|
||||
{
|
||||
tileIndexMap.put( n.nid, getTileIndex( n.ilon, n.ilat ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextWay( WayData data ) throws Exception
|
||||
{
|
||||
// propagate the cycleway-bit
|
||||
if ( cyclewayset.contains( data.wid ) )
|
||||
{
|
||||
data.description |= 2;
|
||||
}
|
||||
|
||||
long waytileset = 0;
|
||||
int nnodes = data.nodes.size();
|
||||
|
||||
// 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 );
|
||||
}
|
||||
}
|
||||
|
||||
// now write way to all tiles hit
|
||||
for( int tileIndex=0; tileIndex<54; tileIndex++ )
|
||||
{
|
||||
if ( ( waytileset & ( 1L << tileIndex ) ) == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
data.writeTo( getOutStreamForTile( tileIndex ) );
|
||||
}
|
||||
}
|
||||
|
||||
private int getTileIndex( int ilon, int ilat )
|
||||
{
|
||||
int lon = ilon / 45000000;
|
||||
int lat = ilat / 30000000;
|
||||
if ( lon < 0 || lon > 7 || lat < 0 || lat > 5 ) throw new IllegalArgumentException( "illegal pos: " + ilon + "," + ilat );
|
||||
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 + ".wtl";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
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.util.HashMap;
|
||||
|
||||
import btools.util.*;
|
||||
|
||||
/**
|
||||
* 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 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 <node-tiles-in> <way-tiles-in> <way-tiles-out> <border-nids-out>" );
|
||||
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 void wayFileStart( File wayfile ) throws Exception
|
||||
{
|
||||
// read corresponding node-file into tileIndexMap
|
||||
String name = wayfile.getName();
|
||||
String nodefilename = name.substring( 0, name.length()-3 ) + "tlf";
|
||||
File nodefile = new File( nodeTilesIn, nodefilename );
|
||||
|
||||
tileIndexMap = Boolean.getBoolean( "useDenseMaps" ) ? new DenseLongMap( 6 ) : new TinyDenseLongMap();
|
||||
lonoffset = -1;
|
||||
latoffset = -1;
|
||||
new NodeIterator( this, false ).processFile( nodefile );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextNode( NodeData n ) throws Exception
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
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.util.HashMap;
|
||||
|
||||
import btools.util.*;
|
||||
|
||||
/**
|
||||
* Container for waydata on the preprocessor level
|
||||
*
|
||||
* @author ab
|
||||
*/
|
||||
public class WayData extends MapCreatorBase
|
||||
{
|
||||
public long wid;
|
||||
public long description;
|
||||
public LongList nodes;
|
||||
|
||||
public WayData( long id )
|
||||
{
|
||||
wid = id;
|
||||
nodes = new LongList( 16 );
|
||||
}
|
||||
|
||||
public WayData( long id, LongList nodes )
|
||||
{
|
||||
wid = id;
|
||||
this.nodes = nodes;
|
||||
}
|
||||
|
||||
public WayData( DataInputStream di ) throws Exception
|
||||
{
|
||||
nodes = new LongList( 16 );
|
||||
wid = readId( di) ;
|
||||
description = di.readLong();
|
||||
for (;;)
|
||||
{
|
||||
long nid = readId( di );
|
||||
if ( nid == -1 ) break;
|
||||
nodes.add( nid );
|
||||
}
|
||||
}
|
||||
|
||||
public void writeTo( DataOutputStream dos ) throws Exception
|
||||
{
|
||||
writeId( dos, wid );
|
||||
dos.writeLong( description );
|
||||
int size = nodes.size();
|
||||
for( int i=0; i < size; i++ )
|
||||
{
|
||||
writeId( dos, nodes.get( i ) );
|
||||
}
|
||||
writeId( dos, -1 ); // stopbyte
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
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.util.HashMap;
|
||||
|
||||
import btools.util.*;
|
||||
|
||||
/**
|
||||
* Iterate over a singe wayfile or a directory
|
||||
* of waytiles and feed the ways to the callback listener
|
||||
*
|
||||
* @author ab
|
||||
*/
|
||||
public class WayIterator extends MapCreatorBase
|
||||
{
|
||||
private WayListener listener;
|
||||
private boolean delete;
|
||||
|
||||
public WayIterator( WayListener wayListener, boolean deleteAfterReading )
|
||||
{
|
||||
listener = wayListener;
|
||||
delete = deleteAfterReading;
|
||||
}
|
||||
|
||||
public void processDir( File indir, String inSuffix ) throws Exception
|
||||
{
|
||||
if ( !indir.isDirectory() )
|
||||
{
|
||||
throw new IllegalArgumentException( "not a directory: " + indir );
|
||||
}
|
||||
|
||||
File[] af = sortBySizeAsc( indir.listFiles() );
|
||||
for( int i=0; i<af.length; i++ )
|
||||
{
|
||||
File wayfile = af[i];
|
||||
if ( wayfile.getName().endsWith( inSuffix ) )
|
||||
{
|
||||
processFile( wayfile );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void processFile(File wayfile) throws Exception
|
||||
{
|
||||
System.out.println( "*** WayIterator reading: " + wayfile );
|
||||
|
||||
listener.wayFileStart( wayfile );
|
||||
|
||||
DataInputStream di = new DataInputStream( new BufferedInputStream ( new FileInputStream( wayfile ) ) );
|
||||
try
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
WayData w = new WayData( di );
|
||||
listener.nextWay( w );
|
||||
}
|
||||
}
|
||||
catch( EOFException eof )
|
||||
{
|
||||
di.close();
|
||||
}
|
||||
listener.wayFileEnd( wayfile );
|
||||
if ( delete && "true".equals( System.getProperty( "deletetmpfiles" ) ))
|
||||
{
|
||||
wayfile.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,289 @@
|
|||
package btools.mapcreator;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import btools.util.*;
|
||||
|
||||
import btools.expressions.BExpressionContext;
|
||||
|
||||
/**
|
||||
* WayLinker finally puts the pieces together
|
||||
* to create the rd5 files. For each 5*5 tile,
|
||||
* the corresponding nodefile and wayfile is read,
|
||||
* plus the (global) bordernodes file, and an rd5
|
||||
* is written
|
||||
*
|
||||
* @author ab
|
||||
*/
|
||||
public class WayLinker extends MapCreatorBase
|
||||
{
|
||||
private File nodeTilesIn;
|
||||
private File dataTilesOut;
|
||||
private File borderFileIn;
|
||||
|
||||
private String dataTilesSuffix;
|
||||
|
||||
private boolean readingBorder;
|
||||
|
||||
private CompactLongMap<OsmNodeP> nodesMap;
|
||||
private List<OsmNodeP> nodesList;
|
||||
private CompactLongSet borderSet;
|
||||
private short lookupVersion;
|
||||
|
||||
private BExpressionContext expctxWay;
|
||||
|
||||
private int minLon;
|
||||
private int minLat;
|
||||
|
||||
private void reset()
|
||||
{
|
||||
minLon = -1;
|
||||
minLat = -1;
|
||||
nodesMap = new CompactLongMap<OsmNodeP>();
|
||||
borderSet = new CompactLongSet();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception
|
||||
{
|
||||
System.out.println("*** WayLinker: Format a regionof an OSM map for routing");
|
||||
if (args.length != 7)
|
||||
{
|
||||
System.out.println("usage: java WayLinker <node-tiles-in> <way-tiles-in> <bordernodes> <lookup-file> <profile-file> <data-tiles-out> <data-tiles-suffix> ");
|
||||
return;
|
||||
}
|
||||
new WayLinker().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[6] );
|
||||
}
|
||||
|
||||
public void process( File nodeTilesIn, File wayTilesIn, File borderFileIn, File lookupFile, File profileFile, File dataTilesOut, String dataTilesSuffix ) throws Exception
|
||||
{
|
||||
this.nodeTilesIn = nodeTilesIn;
|
||||
this.dataTilesOut = dataTilesOut;
|
||||
this.borderFileIn = borderFileIn;
|
||||
this.dataTilesSuffix = dataTilesSuffix;
|
||||
|
||||
// read lookup file to get the lookup-version
|
||||
expctxWay = new BExpressionContext("way");
|
||||
expctxWay.readMetaData( lookupFile );
|
||||
lookupVersion = expctxWay.lookupVersion;
|
||||
expctxWay.parseFile( profileFile, "global" );
|
||||
|
||||
// then process all segments
|
||||
new WayIterator( this, true ).processDir( wayTilesIn, ".wt5" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void wayFileStart( File wayfile ) throws Exception
|
||||
{
|
||||
// process corresponding node-file, if any
|
||||
File nodeFile = fileFromTemplate( wayfile, nodeTilesIn, "u5d" );
|
||||
if ( nodeFile.exists() )
|
||||
{
|
||||
reset();
|
||||
|
||||
// read the border file
|
||||
readingBorder = true;
|
||||
new NodeIterator( this, false ).processFile( borderFileIn );
|
||||
borderSet = new FrozenLongSet( borderSet );
|
||||
|
||||
// read this tile's nodes
|
||||
readingBorder = false;
|
||||
new NodeIterator( this, false ).processFile( nodeFile );
|
||||
|
||||
// freeze the nodes-map
|
||||
FrozenLongMap<OsmNodeP> nodesMapFrozen = new FrozenLongMap<OsmNodeP>( nodesMap );
|
||||
nodesMap = nodesMapFrozen;
|
||||
nodesList = nodesMapFrozen.getValueList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextNode( NodeData data ) throws Exception
|
||||
{
|
||||
OsmNodeP n = data.description == 0L ? new OsmNodeP() : new OsmNodePT(data.description);
|
||||
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 );
|
||||
}
|
||||
|
||||
if ( readingBorder )
|
||||
{
|
||||
borderSet.fastAdd( data.nid );
|
||||
return;
|
||||
}
|
||||
|
||||
// remember the segment coords
|
||||
int min_lon = (n.ilon / 5000000 ) * 5000000;
|
||||
int min_lat = (n.ilat / 5000000 ) * 5000000;
|
||||
if ( minLon == -1 ) minLon = min_lon;
|
||||
if ( minLat == -1 ) minLat = min_lat;
|
||||
if ( minLat != min_lat || minLon != min_lon )
|
||||
throw new IllegalArgumentException( "inconsistent node: " + n.ilon + " " + n.ilat );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextWay( WayData way ) throws Exception
|
||||
{
|
||||
long description = way.description;
|
||||
long reverseDescription = description | 1L; // (add reverse bit)
|
||||
|
||||
// filter according to profile
|
||||
expctxWay.evaluate( description, null );
|
||||
boolean ok = expctxWay.getCostfactor() < 10000.;
|
||||
expctxWay.evaluate( reverseDescription, null );
|
||||
ok |= expctxWay.getCostfactor() < 10000.;
|
||||
|
||||
if ( !ok ) return;
|
||||
|
||||
byte lowbyte = (byte)description;
|
||||
|
||||
OsmNodeP n1 = null;
|
||||
OsmNodeP n2 = null;
|
||||
for (int i=0; i<way.nodes.size(); i++)
|
||||
{
|
||||
long nid = way.nodes.get(i);
|
||||
n1 = n2;
|
||||
n2 = nodesMap.get( nid );
|
||||
if ( n1 != null && n2 != null )
|
||||
{
|
||||
OsmLinkP l1 = new OsmLinkP();
|
||||
l1.targetNode = n2;
|
||||
l1.descriptionBitmap = description;
|
||||
n1.addLink( l1 );
|
||||
|
||||
OsmLinkP l2 = new OsmLinkP();
|
||||
l2.targetNode = n1;
|
||||
l2.descriptionBitmap = reverseDescription;
|
||||
|
||||
n2.addLink( l2 );
|
||||
}
|
||||
if ( n2 != null )
|
||||
{
|
||||
n2.wayAndBits &= lowbyte;
|
||||
if ( n2 instanceof OsmNodePT ) ((OsmNodePT)n2).wayOrBits |= lowbyte;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void wayFileEnd( File wayfile ) throws Exception
|
||||
{
|
||||
nodesMap = null;
|
||||
borderSet = null;
|
||||
|
||||
int maxLon = minLon + 5000000;
|
||||
int maxLat = minLat + 5000000;
|
||||
|
||||
// write segment data to individual files
|
||||
{
|
||||
int nLonSegs = (maxLon - minLon)/1000000;
|
||||
int nLatSegs = (maxLat - minLat)/1000000;
|
||||
|
||||
// sort the nodes into segments
|
||||
LazyArrayOfLists<OsmNodeP> seglists = new LazyArrayOfLists<OsmNodeP>(nLonSegs*nLatSegs);
|
||||
for( OsmNodeP n : nodesList )
|
||||
{
|
||||
if ( n == null || n.firstlink == null || n.isTransferNode() ) continue;
|
||||
if ( n.ilon < minLon || n.ilon >= maxLon
|
||||
|| n.ilat < minLat || n.ilat >= maxLat ) continue;
|
||||
int lonIdx = (n.ilon-minLon)/1000000;
|
||||
int latIdx = (n.ilat-minLat)/1000000;
|
||||
|
||||
int tileIndex = lonIdx * nLatSegs + latIdx;
|
||||
seglists.getList(tileIndex).add( n );
|
||||
}
|
||||
nodesList = null;
|
||||
seglists.trimAll();
|
||||
|
||||
// open the output file
|
||||
File outfile = fileFromTemplate( wayfile, dataTilesOut, dataTilesSuffix );
|
||||
DataOutputStream os = createOutStream( outfile );
|
||||
|
||||
// write 5*5 index dummy
|
||||
long[] fileIndex = new long[25];
|
||||
for( int i55=0; i55<25; i55++)
|
||||
{
|
||||
os.writeLong( 0 );
|
||||
}
|
||||
long filepos = 200L;
|
||||
|
||||
// sort further in 1/80-degree squares
|
||||
for( int lonIdx = 0; lonIdx < nLonSegs; lonIdx++ )
|
||||
{
|
||||
for( int latIdx = 0; latIdx < nLatSegs; latIdx++ )
|
||||
{
|
||||
int tileIndex = lonIdx * nLatSegs + latIdx;
|
||||
if ( seglists.getSize(tileIndex) > 0 )
|
||||
{
|
||||
List<OsmNodeP> nlist = seglists.getList(tileIndex);
|
||||
|
||||
LazyArrayOfLists<OsmNodeP> subs = new LazyArrayOfLists<OsmNodeP>(6400);
|
||||
byte[][] subByteArrays = new byte[6400][];
|
||||
for( int ni=0; ni<nlist.size(); ni++ )
|
||||
{
|
||||
OsmNodeP n = nlist.get(ni);
|
||||
int subLonIdx = (n.ilon - minLon) / 12500 - 80*lonIdx;
|
||||
int subLatIdx = (n.ilat - minLat) / 12500 - 80*latIdx;
|
||||
int si = subLatIdx*80 + subLonIdx;
|
||||
subs.getList(si).add( n );
|
||||
}
|
||||
subs.trimAll();
|
||||
int[] posIdx = new int[6400];
|
||||
int pos = 25600;
|
||||
for( int si=0; si<6400; si++)
|
||||
{
|
||||
List<OsmNodeP> subList = subs.getList(si);
|
||||
if ( subList.size() > 0 )
|
||||
{
|
||||
Collections.sort( subList );
|
||||
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream( );
|
||||
DataOutputStream dos = new DataOutputStream( bos );
|
||||
dos.writeInt( subList.size() );
|
||||
for( int ni=0; ni<subList.size(); ni++ )
|
||||
{
|
||||
OsmNodeP n = subList.get(ni);
|
||||
n.writeNodeData( dos );
|
||||
}
|
||||
dos.close();
|
||||
byte[] subBytes = bos.toByteArray();
|
||||
pos += subBytes.length;
|
||||
subByteArrays[si] = subBytes;
|
||||
}
|
||||
posIdx[si] = pos;
|
||||
}
|
||||
|
||||
for( int si=0; si<6400; si++)
|
||||
{
|
||||
os.writeInt( posIdx[si] );
|
||||
}
|
||||
for( int si=0; si<6400; si++)
|
||||
{
|
||||
if ( subByteArrays[si] != null )
|
||||
{
|
||||
os.write( subByteArrays[si] );
|
||||
}
|
||||
}
|
||||
filepos += pos;
|
||||
}
|
||||
fileIndex[ tileIndex ] = filepos;
|
||||
}
|
||||
}
|
||||
os.close();
|
||||
|
||||
// re-open random-access to write file-index
|
||||
RandomAccessFile ra = new RandomAccessFile( outfile, "rw" );
|
||||
long versionPrefix = lookupVersion;
|
||||
versionPrefix <<= 48;
|
||||
for( int i55=0; i55<25; i55++)
|
||||
{
|
||||
ra.writeLong( fileIndex[i55] | versionPrefix );
|
||||
}
|
||||
ra.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package btools.mapcreator;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Callbacklistener for WayIterator
|
||||
*
|
||||
* @author ab
|
||||
*/
|
||||
public interface WayListener
|
||||
{
|
||||
void wayFileStart( File wayfile ) throws Exception;
|
||||
|
||||
void nextWay( WayData data ) throws Exception;
|
||||
|
||||
void wayFileEnd( File wayfile ) throws Exception;
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
package btools.mapcreator;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import java.net.URL;
|
||||
import java.io.File;
|
||||
|
||||
public class MapcreatorTest
|
||||
{
|
||||
@Test
|
||||
public void mapcreatorTest() throws Exception
|
||||
{
|
||||
URL mapurl = this.getClass().getResource( "/dreieich.osm.gz" );
|
||||
Assert.assertTrue( "test-osm-map dreieich.osm not found", mapurl != null );
|
||||
File mapfile = new File(mapurl.getFile());
|
||||
File workingDir = mapfile.getParentFile();
|
||||
File tmpdir = new File( workingDir, "tmp" );
|
||||
tmpdir.mkdir();
|
||||
|
||||
// run OsmCutter
|
||||
File nodetiles = new File( tmpdir, "nodetiles" );
|
||||
nodetiles.mkdir();
|
||||
File lookupFile = new File( workingDir, "lookups.dat" );
|
||||
File wayFile = new File( tmpdir, "ways.dat" );
|
||||
File relFile = new File( tmpdir, "cycleways.dat" );
|
||||
new OsmCutter().process( lookupFile, nodetiles, wayFile, relFile, mapfile );
|
||||
|
||||
// run NodeFilter
|
||||
File ftiles = new File( tmpdir, "ftiles" );
|
||||
ftiles.mkdir();
|
||||
new NodeFilter().process( nodetiles, wayFile, ftiles );
|
||||
|
||||
// run WayCutter
|
||||
File waytiles = new File( tmpdir, "waytiles" );
|
||||
waytiles.mkdir();
|
||||
new WayCutter().process( ftiles, wayFile, waytiles, relFile );
|
||||
|
||||
// run WayCutter5
|
||||
File waytiles55 = new File( tmpdir, "waytiles55" );
|
||||
File bordernids = new File( tmpdir, "bordernids.dat" );
|
||||
waytiles55.mkdir();
|
||||
new WayCutter5().process( ftiles, waytiles, waytiles55, bordernids );
|
||||
|
||||
// run NodeCutter
|
||||
File nodes55 = new File( tmpdir, "nodes55" );
|
||||
nodes55.mkdir();
|
||||
new NodeCutter().process( ftiles, nodes55 );
|
||||
|
||||
// run PosUnifier
|
||||
File unodes55 = new File( tmpdir, "unodes55" );
|
||||
File bordernodes = new File( tmpdir, "bordernodes.dat" );
|
||||
unodes55.mkdir();
|
||||
new PosUnifier().process( nodes55, unodes55, bordernids, bordernodes, "/private-backup/srtm" );
|
||||
|
||||
// run WayLinker
|
||||
File segments = new File( tmpdir, "segments" );
|
||||
segments.mkdir();
|
||||
File profileAllFile = new File( workingDir, "all.brf" );
|
||||
new WayLinker().process( unodes55, waytiles55, bordernodes, lookupFile, profileAllFile, segments, "rd5" );
|
||||
|
||||
// run WayLinker, car subset
|
||||
File carsubset = new File( segments, "carsubset" );
|
||||
carsubset.mkdir();
|
||||
File profileCarFile = new File( workingDir, "car-test.brf" );
|
||||
new WayLinker().process( unodes55, waytiles55, bordernodes, lookupFile, profileCarFile, carsubset, "cd5" );
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
package btools.mapcreator;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import java.net.URL;
|
||||
import java.io.File;
|
||||
|
||||
public class MapcreatorTest
|
||||
{
|
||||
@Test
|
||||
public void mapcreatorTest() throws Exception
|
||||
{
|
||||
URL mapurl = this.getClass().getResource( "/dreieich.osm.gz" );
|
||||
Assert.assertTrue( "test-osm-map dreieich.osm not found", mapurl != null );
|
||||
File mapfile = new File(mapurl.getFile());
|
||||
File workingDir = mapfile.getParentFile();
|
||||
File tmpdir = new File( workingDir, "tmp" );
|
||||
tmpdir.mkdir();
|
||||
|
||||
// run OsmCutter
|
||||
File nodetiles = new File( tmpdir, "nodetiles" );
|
||||
nodetiles.mkdir();
|
||||
File lookupFile = new File( workingDir, "lookups.dat" );
|
||||
File wayFile = new File( tmpdir, "ways.dat" );
|
||||
File relFile = new File( tmpdir, "cycleways.dat" );
|
||||
new OsmCutter().process( lookupFile, nodetiles, wayFile, relFile, mapfile );
|
||||
|
||||
// run NodeFilter
|
||||
File ftiles = new File( tmpdir, "ftiles" );
|
||||
ftiles.mkdir();
|
||||
new NodeFilter().process( nodetiles, wayFile, ftiles );
|
||||
|
||||
// run WayCutter
|
||||
File waytiles = new File( tmpdir, "waytiles" );
|
||||
waytiles.mkdir();
|
||||
new WayCutter().process( ftiles, wayFile, waytiles, relFile );
|
||||
|
||||
// run WayCutter5
|
||||
File waytiles55 = new File( tmpdir, "waytiles55" );
|
||||
File bordernids = new File( tmpdir, "bordernids.dat" );
|
||||
waytiles55.mkdir();
|
||||
new WayCutter5().process( ftiles, waytiles, waytiles55, bordernids );
|
||||
|
||||
// run NodeCutter
|
||||
File nodes55 = new File( tmpdir, "nodes55" );
|
||||
nodes55.mkdir();
|
||||
new NodeCutter().process( ftiles, nodes55 );
|
||||
|
||||
// run PosUnifier
|
||||
File unodes55 = new File( tmpdir, "unodes55" );
|
||||
File bordernodes = new File( tmpdir, "bordernodes.dat" );
|
||||
unodes55.mkdir();
|
||||
new PosUnifier().process( nodes55, unodes55, bordernids, bordernodes, "/private-backup/srtm" );
|
||||
|
||||
// run WayLinker
|
||||
File segments = new File( tmpdir, "segments" );
|
||||
segments.mkdir();
|
||||
File profileAllFile = new File( workingDir, "all.brf" );
|
||||
new WayLinker().process( unodes55, waytiles55, bordernodes, lookupFile, segments, "rd5" );
|
||||
|
||||
// run WayLinker, car subset
|
||||
File carsubset = new File( segments, "carsubset" );
|
||||
carsubset.mkdir();
|
||||
File profileCarFile = new File( workingDir, "car-test.brf" );
|
||||
new WayLinker().process( unodes55, waytiles55, bordernodes, lookupFile, carsubset, "cd5" );
|
||||
}
|
||||
}
|
||||
18
brouter-map-creator/src/test/resources/all.brf
Normal file
18
brouter-map-creator/src/test/resources/all.brf
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
---context:global # following code refers to global config
|
||||
|
||||
# the elevation parameters
|
||||
|
||||
assign downhillcost 0
|
||||
assign downhillcutoff 1.5
|
||||
assign uphillcost 0
|
||||
assign uphillcutoff 1.5
|
||||
|
||||
---context:way # following code refers to way-tags
|
||||
|
||||
assign turncost 0
|
||||
assign initialcost 0
|
||||
assign costfactor 1
|
||||
|
||||
---context:node # following code refers to node tags
|
||||
|
||||
assign initialcost 0
|
||||
11
brouter-map-creator/src/test/resources/all.brf.BAK
Normal file
11
brouter-map-creator/src/test/resources/all.brf.BAK
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
---context:global # following code refers to global config
|
||||
|
||||
---context:way # following code refers to way-tags
|
||||
|
||||
assign turncost 0
|
||||
assign initialcost 0
|
||||
assign costfactor 1
|
||||
|
||||
---context:node # following code refers to node tags
|
||||
|
||||
assign initialcost 0
|
||||
107
brouter-map-creator/src/test/resources/car-test.brf
Normal file
107
brouter-map-creator/src/test/resources/car-test.brf
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
#
|
||||
# Car-Routing is experimantal !!!
|
||||
#
|
||||
# DO NOT USE FOR ACTUAL NAVIGATION
|
||||
#
|
||||
# Turn restrictions are missing, leading to wrong routes
|
||||
#
|
||||
|
||||
---context:global
|
||||
|
||||
assign downhillcost 0
|
||||
assign downhillcutoff 0
|
||||
assign uphillcost 0
|
||||
assign uphillcutoff 0
|
||||
|
||||
assign validForCars 1
|
||||
|
||||
---context:way # following code refers to way-tags
|
||||
|
||||
assign turncost 200
|
||||
assign initialcost switch highway=ferry 20000 0
|
||||
|
||||
|
||||
#
|
||||
# calculate logical car access
|
||||
#
|
||||
assign caraccess
|
||||
switch motorcar=
|
||||
switch motor_vehicle=
|
||||
switch vehicle=
|
||||
switch access=
|
||||
switch or highway=motorway highway=motorway_link 1
|
||||
switch or highway=trunk highway=trunk_link 1
|
||||
switch or highway=primary highway=primary_link 1
|
||||
switch or highway=secondary highway=secondary_link 1
|
||||
switch or highway=tertiary highway=tertiary_link 1
|
||||
switch highway=unclassified 1
|
||||
switch highway=ferry 1
|
||||
switch or highway=residential highway=living_street 1
|
||||
switch highway=service 1
|
||||
0
|
||||
or access=yes or access=designated access=destination
|
||||
or vehicle=yes or vehicle=designated vehicle=destination
|
||||
or motor_vehicle=yes or motor_vehicle=designated motor_vehicle=destination
|
||||
or motorcar=yes or motorcar=designated motorcar=destination
|
||||
|
||||
assign accesspenalty
|
||||
switch caraccess
|
||||
0
|
||||
10000
|
||||
|
||||
assign onewaypenalty
|
||||
switch switch reversedirection=yes
|
||||
switch oneway=
|
||||
junction=roundabout
|
||||
or oneway=yes or oneway=true oneway=1
|
||||
oneway=-1
|
||||
10000
|
||||
0.0
|
||||
|
||||
|
||||
assign ispaved or surface=paved or surface=asphalt or surface=concrete surface=paving_stones
|
||||
|
||||
assign costfactor
|
||||
|
||||
add max onewaypenalty accesspenalty
|
||||
|
||||
switch or highway=motorway highway=motorway_link 1
|
||||
switch or highway=trunk highway=trunk_link 1
|
||||
switch or highway=primary highway=primary_link switch maxspeed=30 2.0 switch maxspeed=50 1.5 1.2
|
||||
switch or highway=secondary highway=secondary_link 1.3
|
||||
switch or highway=tertiary highway=tertiary_link 1.4
|
||||
switch highway=unclassified 1.5
|
||||
switch highway=ferry 5.67
|
||||
switch highway=bridleway 5
|
||||
switch or highway=residential highway=living_street 2
|
||||
switch highway=service 2
|
||||
switch or highway=track or highway=road highway=path
|
||||
switch tracktype=grade1 5
|
||||
switch ispaved 5
|
||||
30
|
||||
10000
|
||||
|
||||
---context:node # following code refers to node tags
|
||||
|
||||
#
|
||||
# calculate logical car access to nodes
|
||||
#
|
||||
assign caraccess
|
||||
switch motorcar=
|
||||
switch motor_vehicle=
|
||||
switch vehicle=
|
||||
switch access=
|
||||
switch barrier=gate 0
|
||||
switch barrier=bollard 0
|
||||
switch barrier=lift_gate 0
|
||||
switch barrier=cycle_barrier 0
|
||||
1
|
||||
or access=yes or access=designated access=destination
|
||||
or vehicle=yes or vehicle=designated vehicle=destination
|
||||
or motor_vehicle=yes or motor_vehicle=designated motor_vehicle=destination
|
||||
or motorcar=yes or motorcar=designated motorcar=destination
|
||||
|
||||
assign initialcost
|
||||
switch caraccess
|
||||
0
|
||||
1000000
|
||||
BIN
brouter-map-creator/src/test/resources/dreieich.osm.gz
Normal file
BIN
brouter-map-creator/src/test/resources/dreieich.osm.gz
Normal file
Binary file not shown.
317
brouter-map-creator/src/test/resources/lookups.dat
Normal file
317
brouter-map-creator/src/test/resources/lookups.dat
Normal file
|
|
@ -0,0 +1,317 @@
|
|||
---lookupversion:2
|
||||
|
||||
---context:way
|
||||
|
||||
highway;0001731794 track
|
||||
highway;0001457935 residential
|
||||
highway;0000968516 service
|
||||
highway;0000756237 footway
|
||||
highway;0000521566 path
|
||||
highway;0000261772 unclassified
|
||||
highway;0000220315 secondary
|
||||
highway;0000207585 tertiary
|
||||
highway;0000103445 steps
|
||||
highway;0000102114 primary
|
||||
highway;0000094484 cycleway
|
||||
highway;0000090388 living_street
|
||||
highway;0000035041 motorway
|
||||
highway;0000029965 pedestrian
|
||||
highway;0000026875 motorway_link
|
||||
highway;0000015054 trunk
|
||||
highway;0000014604 primary_link
|
||||
highway;0000012211 road
|
||||
highway;0000011822 trunk_link
|
||||
highway;0000005882 construction
|
||||
highway;0000005425 bridleway
|
||||
highway;0000005180 secondary_link
|
||||
highway;0000003360 platform
|
||||
highway;0000002616 proposed abandoned
|
||||
highway;0000001374 tertiary_link
|
||||
highway;0000000760 ferry
|
||||
highway;0000000541 raceway
|
||||
highway;0000000346 rest_area
|
||||
highway;0000000300 bus_stop
|
||||
highway;0000000184 services
|
||||
|
||||
tracktype;0000356503 grade2
|
||||
tracktype;0000353482 grade3
|
||||
tracktype;0000281625 grade1
|
||||
tracktype;0000245193 grade4
|
||||
tracktype;0000179135 grade5
|
||||
|
||||
surface;0000363915 asphalt
|
||||
surface;0000303589 paved
|
||||
surface;0000196783 gravel
|
||||
surface;0000137371 ground
|
||||
surface;0000128215 grass
|
||||
surface;0000092748 unpaved
|
||||
surface;0000086579 paving_stones
|
||||
surface;0000066111 cobblestone
|
||||
surface;0000042061 dirt
|
||||
surface;0000026551 concrete
|
||||
surface;0000025631 compacted
|
||||
surface;0000019861 sand
|
||||
surface;0000009400 pebblestone
|
||||
surface;0000003197 fine_gravel
|
||||
|
||||
maxspeed;0000402224 30
|
||||
maxspeed;0000224685 50
|
||||
maxspeed;0000045177 100
|
||||
maxspeed;0000037529 70
|
||||
maxspeed;0000014237 none
|
||||
maxspeed;0000014022 60
|
||||
maxspeed;0000011530 80
|
||||
maxspeed;0000009951 10
|
||||
maxspeed;0000008056 20
|
||||
maxspeed;0000005772 120
|
||||
maxspeed;0000003165 40
|
||||
maxspeed;0000002987 7
|
||||
maxspeed;0000002826 signals
|
||||
maxspeed;0000001933 130
|
||||
|
||||
service;0000221481 parking_aisle
|
||||
service;0000157110 driveway
|
||||
|
||||
lit;0000132495 yes
|
||||
|
||||
lanes;0000098207 2
|
||||
lanes;0000042192 1
|
||||
lanes;0000018533 3
|
||||
lanes;0000004577 4
|
||||
lanes;0000000448 5
|
||||
lanes;0000000318 1.5
|
||||
|
||||
access;0000044859 yes permissive
|
||||
access;0000008452 designated official
|
||||
access;0000028727 destination customers
|
||||
access;0000076985 agricultural forestry
|
||||
access;0000116270 private
|
||||
access;0000028044 no
|
||||
|
||||
foot;0000339384 yes allowed Yes
|
||||
foot;0000125339 designated official
|
||||
foot;0000018945 no
|
||||
foot;0000001562 private
|
||||
foot;0000000279 destination
|
||||
foot;0000008172 permissive
|
||||
|
||||
bicycle;0000302789 yes allowed permissive
|
||||
bicycle;0000108056 designated official
|
||||
bicycle;0000000265 destination
|
||||
bicycle;0000003593 dismount
|
||||
bicycle;0000001426 private
|
||||
bicycle;0000070179 no
|
||||
|
||||
motorcar;0000010111 yes permissive
|
||||
motorcar;0000001537 designated official
|
||||
motorcar;0000007102 destination
|
||||
motorcar;0000016706 agricultural forestry agriculture
|
||||
motorcar;0000002178 private
|
||||
motorcar;0000077771 no
|
||||
|
||||
motor_vehicle;0000013813 yes permissive
|
||||
motor_vehicle;0000002098 designated official
|
||||
motor_vehicle;0000009792 destination
|
||||
motor_vehicle;0000019301 agricultural forestry
|
||||
motor_vehicle;0000006563 private
|
||||
motor_vehicle;0000025491 no
|
||||
|
||||
motorcycle;0000005750 yes permissive
|
||||
motorcycle;0000001158 designated official
|
||||
motorcycle;0000005805 destination
|
||||
motorcycle;0000012401 agricultural forestry
|
||||
motorcycle;0000001180 private
|
||||
motorcycle;0000053955 no
|
||||
|
||||
vehicle;0000000505 yes permissive
|
||||
vehicle;0000000027 designated
|
||||
vehicle;0000007582 destination
|
||||
vehicle;0000004357 agricultural forestry
|
||||
vehicle;0000001155 private
|
||||
vehicle;0000006487 no
|
||||
|
||||
cycleway;0000033575 track
|
||||
cycleway;0000012829 no
|
||||
cycleway;0000011604 lane
|
||||
cycleway;0000008938 opposite
|
||||
cycleway;0000001503 none
|
||||
cycleway;0000001146 right
|
||||
cycleway;0000001031 opposite_track
|
||||
cycleway;0000001029 yes
|
||||
cycleway;0000000856 opposite_lane
|
||||
cycleway;0000000675 both
|
||||
cycleway;0000000665 left
|
||||
cycleway;0000000521 shared
|
||||
cycleway;0000000383 street
|
||||
cycleway;0000000176 segregated
|
||||
|
||||
mtb:scale;0000043968 0
|
||||
mtb:scale;0000019705 1
|
||||
mtb:scale;0000006436 2
|
||||
mtb:scale;0000002702 3
|
||||
mtb:scale;0000001083 4
|
||||
mtb:scale;0000000329 5
|
||||
|
||||
sac_scale;0000049626 hiking
|
||||
sac_scale;0000007933 mountain_hiking
|
||||
sac_scale;0000001160 demanding_mountain_hiking
|
||||
sac_scale;0000000523 yes
|
||||
sac_scale;0000000364 alpine_hiking
|
||||
sac_scale;0000000117 demanding_alpine_hiking
|
||||
|
||||
noexit;0000058492 yes
|
||||
|
||||
motorroad;0000019250 yes
|
||||
|
||||
oneway;0000330245 yes
|
||||
oneway;0000075148 no
|
||||
oneway;0000003679 -1
|
||||
oneway;0000000001 true
|
||||
oneway;0000000001 1
|
||||
|
||||
junction;0000015929 roundabout
|
||||
|
||||
bridge;0000182649 yes viaduct true suspension
|
||||
|
||||
tunnel;0000031626 yes
|
||||
|
||||
lcn;0000018999 yes
|
||||
|
||||
longdistancecycleway;0000000001 yes
|
||||
|
||||
reversedirection;0000000001 yes
|
||||
|
||||
---context:node
|
||||
|
||||
highway;0000100947 turning_circle
|
||||
highway;0000067645 traffic_signals
|
||||
highway;0000047209 crossing
|
||||
highway;0000037164 bus_stop
|
||||
highway;0000006577 motorway_junction
|
||||
highway;0000003811 stop
|
||||
highway;0000002331 mini_roundabout
|
||||
highway;0000001789 milestone
|
||||
highway;0000001692 passing_place
|
||||
highway;0000001289 give_way
|
||||
highway;0000001092 emergency_access_point
|
||||
highway;0000000683 speed_camera
|
||||
highway;0000000672 steps
|
||||
highway;0000000658 incline_steep
|
||||
highway;0000000620 elevator
|
||||
highway;0000000506 street_lamp
|
||||
highway;0000000490 ford
|
||||
highway;0000000458 incline
|
||||
highway;0000000135 rest_area
|
||||
highway;0000000105 path
|
||||
highway;0000000098 emergency_bay
|
||||
highway;0000000096 road
|
||||
highway;0000000087 platform
|
||||
highway;0000000074 services
|
||||
highway;0000000058 track
|
||||
highway;0000000055 service
|
||||
highway;0000000054 footway
|
||||
highway;0000000053 traffic_calming
|
||||
highway;0000000046 toll_bridge
|
||||
highway;0000000037 city_entry
|
||||
|
||||
barrier;0000076979 gate
|
||||
barrier;0000069308 bollard
|
||||
barrier;0000028131 lift_gate
|
||||
barrier;0000017332 cycle_barrier
|
||||
barrier;0000005693 entrance
|
||||
barrier;0000002885 block
|
||||
barrier;0000001065 kissing_gate
|
||||
barrier;0000000828 cattle_grid
|
||||
barrier;0000000602 stile
|
||||
barrier;0000000561 turnstile
|
||||
barrier;0000000512 no
|
||||
barrier;0000000463 fence
|
||||
barrier;0000000417 bump_gate
|
||||
barrier;0000000324 sally_port
|
||||
barrier;0000000283 yes
|
||||
barrier;0000000283 hampshire_gate
|
||||
barrier;0000000236 swing_gate
|
||||
barrier;0000000203 chain
|
||||
barrier;0000000181 toll_booth
|
||||
barrier;0000000180 door
|
||||
barrier;0000000104 chicane
|
||||
barrier;0000000096 tree
|
||||
barrier;0000000087 border_control
|
||||
barrier;0000000077 log
|
||||
barrier;0000000076 traffic_crossing_pole
|
||||
barrier;0000000063 wall
|
||||
barrier;0000000060 fallen_tree
|
||||
barrier;0000000052 stone
|
||||
barrier;0000000048 ditch
|
||||
barrier;0000000031 spikes
|
||||
|
||||
access;0000001309 yes permissive
|
||||
access;0000000118 designated official
|
||||
access;0000000405 destination customers
|
||||
access;0000000276 agricultural forestry
|
||||
access;0000008574 private
|
||||
access;0000002145 no
|
||||
|
||||
foot;0000080681 yes permissive
|
||||
foot;0000000326 designated official
|
||||
foot;0000000023 destination
|
||||
foot;0000000156 private
|
||||
foot;0000009170 no
|
||||
|
||||
bicycle;0000076717 yes permissive
|
||||
bicycle;0000000406 designated official
|
||||
bicycle;0000000018 destination
|
||||
bicycle;0000000081 dismount
|
||||
bicycle;0000000051 private
|
||||
bicycle;0000016121 no
|
||||
|
||||
motorcar;0000005785 yes permissive
|
||||
motorcar;0000000026 designated official
|
||||
motorcar;0000000080 destination
|
||||
motorcar;0000000112 agricultural forestry
|
||||
motorcar;0000000171 private
|
||||
motorcar;0000001817 no
|
||||
|
||||
motor_vehicle;0000000066 yes permissive
|
||||
motor_vehicle;0000000000 designated official
|
||||
motor_vehicle;0000000030 destination
|
||||
motor_vehicle;0000000073 agricultural forestry
|
||||
motor_vehicle;0000000136 private
|
||||
motor_vehicle;0000000469 no
|
||||
|
||||
motorcycle;0000004515 yes permissive
|
||||
motorcycle;0000000007 designated official
|
||||
motorcycle;0000000054 destination
|
||||
motorcycle;0000000027 agricultural forestry
|
||||
motorcycle;0000000063 private
|
||||
motorcycle;0000001637 no
|
||||
|
||||
vehicle;0000000058 yes permissive
|
||||
vehicle;0000000000 designated
|
||||
vehicle;0000000081 destination
|
||||
vehicle;0000000038 agricultural forestry
|
||||
vehicle;0000000041 private
|
||||
vehicle;0000000271 no
|
||||
|
||||
crossing;0000032485 traffic_signals
|
||||
crossing;0000014300 uncontrolled
|
||||
crossing;0000005086 island
|
||||
crossing;0000001565 unmarked
|
||||
crossing;0000001066 no
|
||||
crossing;0000000333 zebra
|
||||
|
||||
railway;0000034039 level_crossing
|
||||
railway;0000010175 crossing
|
||||
|
||||
noexit;0000043010 yes
|
||||
|
||||
entrance;0000015094 yes
|
||||
entrance;0000007079 main
|
||||
entrance;0000000554 service
|
||||
entrance;0000000169 emergency
|
||||
entrance;0000000063 exit
|
||||
entrance;0000000008 private
|
||||
|
||||
lcn;0000018999 yes
|
||||
|
||||
longdistancecycleway;0000000001 yes
|
||||
Loading…
Add table
Add a link
Reference in a new issue