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
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" );
if ( type == null || !"restriction".equals( type ) )
{
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;
String except = r.getTag( "except" );
if ( except != null )
@ -296,23 +277,31 @@ public class OsmCutter extends MapCreatorBase
exceptions |= toBit( "hgv" , 4, except );
}
// System.out.println( "restriction id = " + r.rid + " isPositive=" + isPositive + " fromWid = " + fromWid + " toWid = " + toWid+ " viaNid = " + viaNid );
RestrictionData res = new RestrictionData();
res.isPositive = isPositive;
res.exceptions = exceptions;
res.fromWid = fromWid;
res.toWid = toWid;
res.viaNid = viaNid;
if ( restrictionsDos != null )
for( String restrictionKey : r.getTagsOrNull().keySet() )
{
res.writeTo( restrictionsDos );
}
if ( restrictionCutter != null )
{
restrictionCutter.nextRestriction( res );
}
if ( !( restrictionKey.equals( "restriction" ) || restrictionKey.startsWith( "restriction:" ) ) )
{
continue;
}
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 )

View file

@ -175,11 +175,11 @@ public class OsmNodeP extends OsmLinkP
RestrictionData r = getFirstRestriction();
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.writeShort( r.exceptions );
mc.writeBoolean( r.isPositive );
mc.writeBoolean( r.isPositive() );
mc.writeInt( r.fromLon );
mc.writeInt( r.fromLat );
mc.writeInt( r.toLon );

View file

@ -1,9 +1,14 @@
package btools.mapcreator;
import java.io.BufferedWriter;
import java.io.DataInputStream;
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
@ -12,26 +17,125 @@ import btools.util.LongList;
*/
public class RestrictionData extends MapCreatorBase
{
public boolean isPositive;
public String restrictionKey;
public String restriction;
public short exceptions;
public long fromWid;
public long toWid;
public long viaNid;
public RestrictionData next;
public int viaLon;
public int viaLat;
public int fromLon;
public int fromLat;
public int toLon;
public int toLat;
public boolean badWayMatch;
private static HashMap<String,String> names = new HashMap<>();
private static TreeSet<Long> badTRs = new TreeSet<>();
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
{
isPositive = di.readBoolean();
restrictionKey = unifyName( di.readUTF() );
restriction = unifyName( di.readUTF() );
exceptions = di.readShort();
fromWid = readId( di );
toWid = readId( di );
@ -40,7 +144,8 @@ public class RestrictionData extends MapCreatorBase
public void writeTo( DataOutputStream dos ) throws Exception
{
dos.writeBoolean( isPositive );
dos.writeUTF( restrictionKey );
dos.writeUTF( restriction );
dos.writeShort( exceptions );
writeId( dos, fromWid );
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(
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,
@ -287,6 +290,8 @@ public class WayLinker extends MapCreatorBase implements Runnable
nodesMap.put( res.viaNid, n );
}
OsmNodePT nt = (OsmNodePT) n;
res.viaLon = nt.ilon;
res.viaLat = nt.ilat;
res.next = nt.firstRestriction;
nt.firstRestriction = res;
ntr++;
@ -351,37 +356,50 @@ public class WayLinker extends MapCreatorBase implements Runnable
// the leg according to the mapped direction
private void checkRestriction( OsmNodeP n1, OsmNodeP n2, WayData w )
{
checkRestriction( n1, n2, w.wid, true );
checkRestriction( n2, n1, w.wid, false );
checkRestriction( n1, n2, w, true );
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();
while ( r != null )
{
if ( r.fromWid == wid )
if ( r.fromWid == w.wid )
{
if ( r.fromLon == 0 || checkFrom )
{
r.fromLon = n1.ilon;
r.fromLat = n1.ilat;
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 )
{
r.toLon = n1.ilon;
r.toLat = n1.ilat;
n1.bits |= OsmNodeP.DP_SURVIVOR_BIT;
if ( !isEndNode( n2, w ) )
{
r.badWayMatch = true;
}
}
}
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
public void nextWay( WayData way ) throws Exception
{

View file

@ -140,6 +140,11 @@ public class OsmParser extends MapCreatorBase
rListener.nextRelation( r );
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;
}
for( int fi = 0; fi < fromWid.size(); fi++ )
@ -152,7 +157,7 @@ public class OsmParser extends MapCreatorBase
}
catch( Exception e )
{
throw new RuntimeException( "error writing relation: " + e );
throw new RuntimeException( "error writing relation", e );
}
}