added bad-TRs analysis to pre-processor
This commit is contained in:
parent
8fd38da5c9
commit
771770af22
5 changed files with 163 additions and 46 deletions
|
@ -260,30 +260,11 @@ public class OsmCutter extends MapCreatorBase
|
||||||
@Override
|
@Override
|
||||||
public void nextRestriction( RelationData r, long fromWid, long toWid, long viaNid ) throws Exception
|
public void nextRestriction( RelationData r, long fromWid, long toWid, long viaNid ) throws Exception
|
||||||
{
|
{
|
||||||
if ( fromWid == 0 || toWid == 0 || viaNid == 0 )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String type = r.getTag( "type" );
|
String type = r.getTag( "type" );
|
||||||
if ( type == null || !"restriction".equals( type ) )
|
if ( type == null || !"restriction".equals( type ) )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String restriction = r.getTag( "restriction" );
|
|
||||||
if ( restriction == null )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
boolean isPositive = true;
|
|
||||||
if ( restriction.startsWith( "no_" ) )
|
|
||||||
{
|
|
||||||
isPositive = false;
|
|
||||||
}
|
|
||||||
else if ( !restriction.startsWith( "only_" ) )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
short exceptions = 0;
|
short exceptions = 0;
|
||||||
String except = r.getTag( "except" );
|
String except = r.getTag( "except" );
|
||||||
if ( except != null )
|
if ( except != null )
|
||||||
|
@ -296,23 +277,31 @@ public class OsmCutter extends MapCreatorBase
|
||||||
exceptions |= toBit( "hgv" , 4, except );
|
exceptions |= toBit( "hgv" , 4, except );
|
||||||
}
|
}
|
||||||
|
|
||||||
// System.out.println( "restriction id = " + r.rid + " isPositive=" + isPositive + " fromWid = " + fromWid + " toWid = " + toWid+ " viaNid = " + viaNid );
|
for( String restrictionKey : r.getTagsOrNull().keySet() )
|
||||||
RestrictionData res = new RestrictionData();
|
|
||||||
res.isPositive = isPositive;
|
|
||||||
res.exceptions = exceptions;
|
|
||||||
res.fromWid = fromWid;
|
|
||||||
res.toWid = toWid;
|
|
||||||
res.viaNid = viaNid;
|
|
||||||
|
|
||||||
if ( restrictionsDos != null )
|
|
||||||
{
|
{
|
||||||
res.writeTo( restrictionsDos );
|
if ( !( restrictionKey.equals( "restriction" ) || restrictionKey.startsWith( "restriction:" ) ) )
|
||||||
}
|
{
|
||||||
if ( restrictionCutter != null )
|
continue;
|
||||||
{
|
}
|
||||||
restrictionCutter.nextRestriction( res );
|
String restriction = r.getTag( restrictionKey );
|
||||||
}
|
|
||||||
|
RestrictionData res = new RestrictionData();
|
||||||
|
res.restrictionKey = restrictionKey;
|
||||||
|
res.restriction = restriction;
|
||||||
|
res.exceptions = exceptions;
|
||||||
|
res.fromWid = fromWid;
|
||||||
|
res.toWid = toWid;
|
||||||
|
res.viaNid = viaNid;
|
||||||
|
|
||||||
|
if ( restrictionsDos != null )
|
||||||
|
{
|
||||||
|
res.writeTo( restrictionsDos );
|
||||||
|
}
|
||||||
|
if ( restrictionCutter != null )
|
||||||
|
{
|
||||||
|
restrictionCutter.nextRestriction( res );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static short toBit( String tag, int bitpos, String s )
|
private static short toBit( String tag, int bitpos, String s )
|
||||||
|
|
|
@ -175,11 +175,11 @@ public class OsmNodeP extends OsmLinkP
|
||||||
RestrictionData r = getFirstRestriction();
|
RestrictionData r = getFirstRestriction();
|
||||||
while( r != null )
|
while( r != null )
|
||||||
{
|
{
|
||||||
if ( r.fromLon != 0 && r.toLon != 0 )
|
if ( r.isValid() && r.fromLon != 0 && r.toLon != 0 )
|
||||||
{
|
{
|
||||||
mc.writeBoolean( true ); // restriction follows
|
mc.writeBoolean( true ); // restriction follows
|
||||||
mc.writeShort( r.exceptions );
|
mc.writeShort( r.exceptions );
|
||||||
mc.writeBoolean( r.isPositive );
|
mc.writeBoolean( r.isPositive() );
|
||||||
mc.writeInt( r.fromLon );
|
mc.writeInt( r.fromLon );
|
||||||
mc.writeInt( r.fromLat );
|
mc.writeInt( r.fromLat );
|
||||||
mc.writeInt( r.toLon );
|
mc.writeInt( r.toLon );
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
package btools.mapcreator;
|
package btools.mapcreator;
|
||||||
|
|
||||||
|
import java.io.BufferedWriter;
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
import btools.util.LongList;
|
import btools.util.CheapAngleMeter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Container for a turn restriction
|
* Container for a turn restriction
|
||||||
|
@ -12,26 +17,125 @@ import btools.util.LongList;
|
||||||
*/
|
*/
|
||||||
public class RestrictionData extends MapCreatorBase
|
public class RestrictionData extends MapCreatorBase
|
||||||
{
|
{
|
||||||
public boolean isPositive;
|
public String restrictionKey;
|
||||||
|
public String restriction;
|
||||||
public short exceptions;
|
public short exceptions;
|
||||||
public long fromWid;
|
public long fromWid;
|
||||||
public long toWid;
|
public long toWid;
|
||||||
public long viaNid;
|
public long viaNid;
|
||||||
public RestrictionData next;
|
public RestrictionData next;
|
||||||
|
|
||||||
|
public int viaLon;
|
||||||
|
public int viaLat;
|
||||||
|
|
||||||
public int fromLon;
|
public int fromLon;
|
||||||
public int fromLat;
|
public int fromLat;
|
||||||
|
|
||||||
public int toLon;
|
public int toLon;
|
||||||
public int toLat;
|
public int toLat;
|
||||||
|
|
||||||
|
public boolean badWayMatch;
|
||||||
|
|
||||||
|
private static HashMap<String,String> names = new HashMap<>();
|
||||||
|
private static TreeSet<Long> badTRs = new TreeSet<>();
|
||||||
|
|
||||||
public RestrictionData()
|
public RestrictionData()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isPositive()
|
||||||
|
{
|
||||||
|
return restriction.startsWith( "only_" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isValid()
|
||||||
|
{
|
||||||
|
boolean valid = fromLon != 0 && toLon != 0 && ( restriction.startsWith( "only_" ) || restriction.startsWith( "no_" ) );
|
||||||
|
if ( (!valid) || badWayMatch || !(checkGeometry()) )
|
||||||
|
{
|
||||||
|
synchronized( badTRs )
|
||||||
|
{
|
||||||
|
badTRs.add( ( (long) viaLon ) << 32 | viaLat );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return valid && "restriction".equals( restrictionKey );
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkGeometry()
|
||||||
|
{
|
||||||
|
double a = (new CheapAngleMeter()).calcAngle( fromLon, fromLat, viaLon, viaLat, toLon, toLat );
|
||||||
|
String t;
|
||||||
|
if ( restriction.startsWith( "only_" ) )
|
||||||
|
{
|
||||||
|
t = restriction.substring( "only_".length() );
|
||||||
|
}
|
||||||
|
else if ( restriction.startsWith( "no_" ) )
|
||||||
|
{
|
||||||
|
t = restriction.substring( "no_".length() );
|
||||||
|
}
|
||||||
|
else throw new RuntimeException( "ups" );
|
||||||
|
|
||||||
|
if ( restrictionKey.endsWith( ":conditional" ) )
|
||||||
|
{
|
||||||
|
int idx = t.indexOf( '@' );
|
||||||
|
if ( idx >= 0 )
|
||||||
|
{
|
||||||
|
t = t.substring(0, idx ).trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( "left_turn".equals( t ) )
|
||||||
|
{
|
||||||
|
return a < -5. && a > -175.;
|
||||||
|
}
|
||||||
|
if ( "right_turn".equals( t ) )
|
||||||
|
{
|
||||||
|
return a > 5. && a < 175.;
|
||||||
|
}
|
||||||
|
if ( "straight_on".equals( t ) )
|
||||||
|
{
|
||||||
|
return a > -85. && a < 85.;
|
||||||
|
}
|
||||||
|
if ( "u_turn".equals( t ) )
|
||||||
|
{
|
||||||
|
return a < - 95. || a > 95.;
|
||||||
|
}
|
||||||
|
return "entry".equals( t ) || "exit".equals( t );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String unifyName( String name )
|
||||||
|
{
|
||||||
|
synchronized( names )
|
||||||
|
{
|
||||||
|
String n = names.get(name);
|
||||||
|
if ( n == null )
|
||||||
|
{
|
||||||
|
names.put( name, name );
|
||||||
|
n = name;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void dumpBadTRs()
|
||||||
|
{
|
||||||
|
try( BufferedWriter bw = new BufferedWriter( new FileWriter( "badtrs.txt" ) ) )
|
||||||
|
{
|
||||||
|
for( Long id : badTRs )
|
||||||
|
{
|
||||||
|
bw.write( "" + id + " 26\n" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch( IOException ioe )
|
||||||
|
{
|
||||||
|
throw new RuntimeException( ioe );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public RestrictionData( DataInputStream di ) throws Exception
|
public RestrictionData( DataInputStream di ) throws Exception
|
||||||
{
|
{
|
||||||
isPositive = di.readBoolean();
|
restrictionKey = unifyName( di.readUTF() );
|
||||||
|
restriction = unifyName( di.readUTF() );
|
||||||
exceptions = di.readShort();
|
exceptions = di.readShort();
|
||||||
fromWid = readId( di );
|
fromWid = readId( di );
|
||||||
toWid = readId( di );
|
toWid = readId( di );
|
||||||
|
@ -40,7 +144,8 @@ public class RestrictionData extends MapCreatorBase
|
||||||
|
|
||||||
public void writeTo( DataOutputStream dos ) throws Exception
|
public void writeTo( DataOutputStream dos ) throws Exception
|
||||||
{
|
{
|
||||||
dos.writeBoolean( isPositive );
|
dos.writeUTF( restrictionKey );
|
||||||
|
dos.writeUTF( restriction );
|
||||||
dos.writeShort( exceptions );
|
dos.writeShort( exceptions );
|
||||||
writeId( dos, fromWid );
|
writeId( dos, fromWid );
|
||||||
writeId( dos, toWid );
|
writeId( dos, toWid );
|
||||||
|
|
|
@ -138,6 +138,9 @@ public class WayLinker extends MapCreatorBase implements Runnable
|
||||||
|
|
||||||
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] ), new File(
|
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] ), new File(
|
||||||
args[6] ), args[7] );
|
args[6] ), args[7] );
|
||||||
|
|
||||||
|
System.out.println( "dumping bad TRs" );
|
||||||
|
RestrictionData.dumpBadTRs();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void process( File nodeTilesIn, File wayTilesIn, File borderFileIn, File restrictionsFileIn, File lookupFile, File profileFile, File dataTilesOut,
|
public void process( File nodeTilesIn, File wayTilesIn, File borderFileIn, File restrictionsFileIn, File lookupFile, File profileFile, File dataTilesOut,
|
||||||
|
@ -287,6 +290,8 @@ public class WayLinker extends MapCreatorBase implements Runnable
|
||||||
nodesMap.put( res.viaNid, n );
|
nodesMap.put( res.viaNid, n );
|
||||||
}
|
}
|
||||||
OsmNodePT nt = (OsmNodePT) n;
|
OsmNodePT nt = (OsmNodePT) n;
|
||||||
|
res.viaLon = nt.ilon;
|
||||||
|
res.viaLat = nt.ilat;
|
||||||
res.next = nt.firstRestriction;
|
res.next = nt.firstRestriction;
|
||||||
nt.firstRestriction = res;
|
nt.firstRestriction = res;
|
||||||
ntr++;
|
ntr++;
|
||||||
|
@ -351,36 +356,49 @@ public class WayLinker extends MapCreatorBase implements Runnable
|
||||||
// the leg according to the mapped direction
|
// the leg according to the mapped direction
|
||||||
private void checkRestriction( OsmNodeP n1, OsmNodeP n2, WayData w )
|
private void checkRestriction( OsmNodeP n1, OsmNodeP n2, WayData w )
|
||||||
{
|
{
|
||||||
checkRestriction( n1, n2, w.wid, true );
|
checkRestriction( n1, n2, w, true );
|
||||||
checkRestriction( n2, n1, w.wid, false );
|
checkRestriction( n2, n1, w, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkRestriction( OsmNodeP n1, OsmNodeP n2, long wid, boolean checkFrom )
|
private void checkRestriction( OsmNodeP n1, OsmNodeP n2, WayData w, boolean checkFrom )
|
||||||
{
|
{
|
||||||
RestrictionData r = n2.getFirstRestriction();
|
RestrictionData r = n2.getFirstRestriction();
|
||||||
while ( r != null )
|
while ( r != null )
|
||||||
{
|
{
|
||||||
if ( r.fromWid == wid )
|
if ( r.fromWid == w.wid )
|
||||||
{
|
{
|
||||||
if ( r.fromLon == 0 || checkFrom )
|
if ( r.fromLon == 0 || checkFrom )
|
||||||
{
|
{
|
||||||
r.fromLon = n1.ilon;
|
r.fromLon = n1.ilon;
|
||||||
r.fromLat = n1.ilat;
|
r.fromLat = n1.ilat;
|
||||||
n1.bits |= OsmNodeP.DP_SURVIVOR_BIT;
|
n1.bits |= OsmNodeP.DP_SURVIVOR_BIT;
|
||||||
|
if ( !isEndNode( n2, w ) )
|
||||||
|
{
|
||||||
|
r.badWayMatch = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( r.toWid == wid )
|
if ( r.toWid == w.wid )
|
||||||
{
|
{
|
||||||
if ( r.toLon == 0 || !checkFrom )
|
if ( r.toLon == 0 || !checkFrom )
|
||||||
{
|
{
|
||||||
r.toLon = n1.ilon;
|
r.toLon = n1.ilon;
|
||||||
r.toLat = n1.ilat;
|
r.toLat = n1.ilat;
|
||||||
n1.bits |= OsmNodeP.DP_SURVIVOR_BIT;
|
n1.bits |= OsmNodeP.DP_SURVIVOR_BIT;
|
||||||
|
if ( !isEndNode( n2, w ) )
|
||||||
|
{
|
||||||
|
r.badWayMatch = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
r = r.next;
|
r = r.next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isEndNode( OsmNodeP n, WayData w )
|
||||||
|
{
|
||||||
|
return n == nodesMap.get( w.nodes.get( 0 ) ) || n == nodesMap.get( w.nodes.get( w.nodes.size() - 1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void nextWay( WayData way ) throws Exception
|
public void nextWay( WayData way ) throws Exception
|
||||||
|
|
|
@ -140,6 +140,11 @@ public class OsmParser extends MapCreatorBase
|
||||||
rListener.nextRelation( r );
|
rListener.nextRelation( r );
|
||||||
if ( fromWid == null || toWid == null || viaNid == null || viaNid.size() != 1 )
|
if ( fromWid == null || toWid == null || viaNid == null || viaNid.size() != 1 )
|
||||||
{
|
{
|
||||||
|
// dummy-TR for each viaNid
|
||||||
|
for( int vi = 0; vi < ( viaNid == null ? 0 : viaNid.size() ); vi++ )
|
||||||
|
{
|
||||||
|
rListener.nextRestriction( r, 0L, 0L, viaNid.get( vi ) );
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for( int fi = 0; fi < fromWid.size(); fi++ )
|
for( int fi = 0; fi < fromWid.size(); fi++ )
|
||||||
|
@ -152,7 +157,7 @@ public class OsmParser extends MapCreatorBase
|
||||||
}
|
}
|
||||||
catch( Exception e )
|
catch( Exception e )
|
||||||
{
|
{
|
||||||
throw new RuntimeException( "error writing relation: " + e );
|
throw new RuntimeException( "error writing relation", e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue