added bad-TRs analysis to pre-processor

This commit is contained in:
Arndt Brenschede 2022-01-15 10:05:06 +01:00
parent 8fd38da5c9
commit 771770af22
5 changed files with 163 additions and 46 deletions

View file

@ -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 )

View file

@ -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 );

View file

@ -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 );

View file

@ -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,37 +356,50 @@ 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
{ {

View file

@ -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 );
} }
} }