initail commit suspect detection

This commit is contained in:
Arndt Brenschede 2018-03-10 10:41:11 +01:00
parent e6601b9a61
commit e5d8bd9bf4
8 changed files with 345 additions and 15 deletions

View file

@ -184,7 +184,7 @@ abstract class OsmPath implements OsmLinkHolder
}
// check turn restrictions (n detail mode (=final pass) no TR to not mess up voice hints)
if ( nsection == 0 && rc.considerTurnRestrictions && !detailMode )
if ( nsection == 0 )
{
boolean hasAnyPositive = false;
boolean hasPositive = false;
@ -223,8 +223,23 @@ abstract class OsmPath implements OsmLinkHolder
}
if ( !hasPositive && ( hasAnyPositive || hasNegative ) )
{
cost = -1;
return;
if ( rc.considerTurnRestrictions && !detailMode )
{
cost = -1;
return;
}
if ( !rc.considerTurnRestrictions && detailMode ) // detect effective (=suspect) TRs
{
if ( rc.suspectTRs != null && priorityclassifier > 20 && cost > 2000 && cost < rc.maxcost - 2000 )
{
Long id = Long.valueOf( sourceNode.getIdFromPos() );
if ( rc.suspectTRs.get( id ) == null )
{
System.out.println( "bad TR candidate: " + id );
rc.suspectTRs.put( id, Integer.valueOf( priorityclassifier ) );
}
}
}
}
}
@ -308,8 +323,12 @@ abstract class OsmPath implements OsmLinkHolder
double elevation = ele2 == Short.MIN_VALUE ? 100. : ele2/4.;
double sectionCost = processWaySection( rc, dist, delta_h, elevation, angle, cosangle, isStartpoint, nsection, lastpriorityclassifier );
if ( ( sectionCost < 0. || costfactor > 9998. && !detailMode ) || sectionCost + cost >= 2000000000. )
if ( ( sectionCost < 0. || costfactor > 9996. && !detailMode ) || sectionCost + cost >= 2000000000. )
{
if ( ( costfactor == 9998. && priorityclassifier == lastpriorityclassifier ) || costfactor == 9997. )
{
rc.foundWayBlock = Math.max( rc.foundWayBlock, priorityclassifier );
}
cost = -1;
return;
}
@ -398,6 +417,17 @@ abstract class OsmPath implements OsmLinkHolder
double targetCost = processTargetNode( rc );
if ( targetCost < 0. || targetCost + cost >= 2000000000. )
{
if ( rc.suspectNodes != null && priorityclassifier > 20 && !rc.inverseDirection )
{
rc.foundNodeBlock = true;
Long id = Long.valueOf( targetNode.getIdFromPos() );
Integer val = rc.suspectNodes.get( id );
if ( val == null || priorityclassifier > val.intValue() )
{
rc.suspectNodes.put( id, Integer.valueOf( priorityclassifier ) );
}
}
cost = -1;
return;
}

View file

@ -8,6 +8,7 @@ package btools.router;
import java.io.DataOutput;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -35,6 +36,13 @@ public final class RoutingContext
public String rawTrackPath;
public Map<Long,Integer> suspectNodes;
public Map<Long,Integer> suspectTRs;
public boolean foundNodeBlock;
public int foundWayBlock;
public int maxcost;
public String getProfileName()
{
String name = localFunction == null ? "unknown" : localFunction;
@ -57,7 +65,7 @@ public final class RoutingContext
public int uphillcutoff;
public boolean carMode;
public boolean bikeMode;
public boolean considerTurnRestrictions;
public boolean considerTurnRestrictions = true;
public boolean processUnusedTags;
public boolean forceSecondaryData;
public double pass1coefficient;
@ -131,7 +139,7 @@ public final class RoutingContext
bikeMode = 0.f != expctxGlobal.getVariableValue( "validForBikes", 0.f );
// turn-restrictions used per default for car profiles
considerTurnRestrictions = 0.f != expctxGlobal.getVariableValue( "considerTurnRestrictions", carMode ? 1.f : 0.f );
considerTurnRestrictions = 0.f != expctxGlobal.getVariableValue( "considerTurnRestrictions", carMode && considerTurnRestrictions ? 1.f : 0.f );
// process tags not used in the profile (to have them in the data-tab)
processUnusedTags = 0.f != expctxGlobal.getVariableValue( "processUnusedTags", 0.f );

View file

@ -9,6 +9,7 @@ import java.io.Writer;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import btools.mapaccess.NodesCache;
import btools.mapaccess.OsmLink;
@ -951,6 +952,7 @@ public class RoutingEngine extends Thread
}
routingContext.firstPrePath = null;
routingContext.maxcost = maxTotalCost;
for( OsmLink link = currentNode.firstlink; link != null; link = link.getNext( currentNode) )
{
@ -977,6 +979,10 @@ public class RoutingEngine extends Thread
}
}
int nPathPossible = 0;
routingContext.foundNodeBlock = false;
routingContext.foundWayBlock = 0;
for( OsmLink link = currentNode.firstlink; link != null; link = link.getNext( currentNode) )
{
OsmNode nextNode = link.getTarget( currentNode );
@ -985,14 +991,15 @@ public class RoutingEngine extends Thread
{
continue; // border node?
}
if ( nextNode.firstlink == null )
{
continue; // don't care about dead ends
}
if ( nextNode == sourceNode )
{
continue; // border node?
}
if ( nextNode.firstlink == null )
{
nPathPossible++;
continue; // don't care about dead ends
}
if ( guideTrack != null )
{
@ -1008,11 +1015,14 @@ public class RoutingEngine extends Thread
// not along the guide-track, discard, but register for voice-hint processing
if ( routingContext.turnInstructionMode > 0 )
{
Map<Long,Integer> trSuspects = routingContext.suspectTRs;
routingContext.suspectTRs = null;
OsmPath detour = routingContext.createPath( path, link, refTrack, true );
if ( detour.cost >= 0. && nextId != startNodeId1 && nextId != startNodeId2 )
{
guideTrack.registerDetourForId( currentNode.getIdFromPos(), OsmPathElement.create( detour, false ) );
}
routingContext.suspectTRs = trSuspects;
}
continue;
}
@ -1053,6 +1063,8 @@ public class RoutingEngine extends Thread
}
if ( bestPath != null )
{
nPathPossible++;
boolean trafficSim = endPos == null;
bestPath.airdistance = trafficSim ? keepPathAirdistance : ( isFinalLink ? 0 : nextNode.calcDistance( endPos ) );
@ -1078,7 +1090,6 @@ public class RoutingEngine extends Thread
{
bestPath.airdistance += boundary.getBoundaryDistance( nextNode );
}
bestPath.treedepth = path.treedepth + 1;
link.addLinkHolder( bestPath, currentNode );
synchronized( openSet )
@ -1090,6 +1101,29 @@ public class RoutingEngine extends Thread
}
}
// report oneway dead-ends as suspects
if ( routingContext.suspectNodes != null && path.priorityclassifier > 20 && currentNode.virgin && path.cost > 2000 && !routingContext.inverseDirection )
{
int suspectPrio = 0;
if ( nPathPossible == 0 && (!routingContext.foundNodeBlock) )
{
suspectPrio = path.priorityclassifier;
}
else if ( routingContext.foundWayBlock != 0 )
{
suspectPrio = routingContext.foundWayBlock;
}
if ( suspectPrio > 20 )
{
Long id = Long.valueOf( currentNode.getIdFromPos() );
Integer val = routingContext.suspectNodes.get( id );
if ( val == null || suspectPrio > val.intValue() )
{
routingContext.suspectNodes.put( id, Integer.valueOf( suspectPrio ) );
}
}
}
path.unregisterUpTree( routingContext );
}
return null;
@ -1180,7 +1214,7 @@ public class RoutingEngine extends Thread
track.buildMap();
// for final track..
if ( guideTrack != null )
if ( guideTrack != null && routingContext.turnInstructionMode > 0 )
{
track.copyDetours( guideTrack );
track.processVoiceHints( routingContext );

View file

@ -40,6 +40,8 @@ public class OsmNode extends OsmLink implements OsmPos
*/
public OsmLink firstlink = null;
public boolean virgin = true;
public OsmNode()
{
}
@ -232,6 +234,8 @@ public class OsmNode extends OsmLink implements OsmPos
public final void unlinkLink( OsmLink link )
{
virgin = false;
OsmLink n = link.clear( this );
if ( link == firstlink )

View file

@ -135,7 +135,7 @@ public class BRouter
}
private static OsmNodeNamed readPosition( String[] args, int idx, String name )
public static OsmNodeNamed readPosition( String[] args, int idx, String name )
{
OsmNodeNamed n = new OsmNodeNamed();
n.name = name;

View file

@ -0,0 +1,93 @@
package btools.server;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import btools.router.OsmNodeNamed;
import btools.router.RoutingContext;
import btools.router.RoutingEngine;
public class BadTRDetector
{
public static void main(String[] args) throws Exception
{
System.out.println("BadTRDetector / 15102017 / abrensch");
if ( args.length < 7 )
{
System.out.println("Find bad TR candidates in OSM");
System.out.println("usage: java BadTRDetector <segmentdir> <lon-from> <lat-from> <lon-to> <lat-to> <profile> <nshots>");
return;
}
int nshots = Integer.parseInt( args[6] );
boolean findTrs = false;
if ( nshots < 0 )
{
findTrs = true;
nshots = -nshots;
}
OsmNodeNamed lowerLeft = BRouter.readPosition( args, 1, "lowerLeft" );
OsmNodeNamed uppperRight = BRouter.readPosition( args, 3, "uppperRight" );
Random rand = new Random();
Map<Long,Integer> suspectTRs = new HashMap<Long,Integer>();
for( int nshot = 0; nshot < nshots; nshot++ )
{
OsmNodeNamed n = new OsmNodeNamed();
n.name = "from";
n.ilon = lowerLeft.ilon + (int)(rand.nextDouble() * ( uppperRight.ilon - lowerLeft.ilon ) );
n.ilat = lowerLeft.ilat + (int)(rand.nextDouble() * ( uppperRight.ilat - lowerLeft.ilat ) );
// target ca 10km weg
OsmNodeNamed t = new OsmNodeNamed();
n.name = "to";
double dir = rand.nextDouble() + 2. * Math.PI;
t.ilon = n.ilon + (int)( 300000. * Math.sin( dir ) );
t.ilat = n.ilat + (int)( 200000. * Math.cos( dir ) );
List<OsmNodeNamed> wplist = new ArrayList<OsmNodeNamed>();
wplist.add( n );
wplist.add( t );
RoutingContext rc = new RoutingContext();
rc.localFunction = args[5];
rc.memoryclass = (int) ( Runtime.getRuntime().maxMemory() / 1024 / 1024 );
if ( findTrs )
{
rc.suspectTRs = suspectTRs;
rc.considerTurnRestrictions = false;
}
else
{
rc.suspectNodes = suspectTRs;
}
RoutingEngine re = new RoutingEngine( "mytrack", "mylog", args[0], wplist, rc );
re.doRun( 5000 );
if ( re.getErrorMessage() != null )
{
System.out.println( re.getErrorMessage() );
}
}
// write tr-suspects to file
String suspectsFile = "deadend.suspects";
BufferedWriter bw = new BufferedWriter( new FileWriter( new File( suspectsFile ) ) );
for( Long suspect : suspectTRs.keySet() )
{
bw.write( suspect + " " + suspectTRs.get( suspect ) + "\r\n" );
}
bw.close();
}
}

View file

@ -0,0 +1,40 @@
package btools.server;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
public class IssueFilter
{
public static void main(String[] args) throws Exception
{
if ( args.length != 2 )
{
System.out.println( "usage : IssueFilter <in-file> <out-file> " );
System.exit(1);
}
BufferedReader br = new BufferedReader( new FileReader( new File( args[0] ) ) );
BufferedWriter bw = new BufferedWriter( new FileWriter( new File( args[1] ) ) );
for(;;)
{
String line = br.readLine();
if ( line == null ) break;
if ( line.startsWith( "bad TR candidate: " ) )
{
bw.write( line.substring( "bad TR candidate: ".length() ) );
bw.write( "\r\n" );
}
}
br.close();
bw.close();
}
}

View file

@ -0,0 +1,121 @@
package btools.server;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;
public class IssueSorter
{
public static void main(String[] args) throws Exception
{
if ( args.length < 2 )
{
System.out.println( "usage : IssueSorter <in-file> <out-file> [<osm-filter>]" );
System.exit(1);
}
File osmFilter = args.length > 2 ? new File( args[2] ) : null;
Set<Long> filterSet = null;
// if the osm-filter exists, read it
if ( osmFilter != null && osmFilter.exists() )
{
filterSet = new HashSet<Long>();
BufferedReader r = new BufferedReader( new FileReader( osmFilter ) );
for(;;)
{
String line = r.readLine();
if ( line == null ) break;
int idx0 = line.indexOf( "<node id=\"" );
if ( idx0 < 0 ) continue;
idx0 += 10;
int idx1 = line.indexOf( '"', idx0 );
long nodeId = Long.parseLong( line.substring( idx0, idx1 ) );
filterSet.add( Long.valueOf( nodeId ) );
}
r.close();
}
TreeMap<String,TreeMap<Long,Integer>> keys = new TreeMap<String,TreeMap<Long,Integer>>();
BufferedReader br = new BufferedReader( new FileReader( new File( args[0] ) ) );
for(;;)
{
String line = br.readLine();
if ( line == null ) break;
StringTokenizer tk = new StringTokenizer( line );
long id = Long.parseLong( tk.nextToken() );
int prio = Integer.parseInt( tk.nextToken() );
if ( filterSet != null && !filterSet.contains( Long.valueOf( id ) ) )
{
continue;
}
int ilon = (int) ( id >> 32 );
int ilat = (int) ( id & 0xffffffff );
String key = getKey( ilon, ilat );
TreeMap<Long,Integer> map = keys.get( key );
if ( map == null )
{
map = new TreeMap<Long,Integer>();
keys.put( key, map );
}
map.put( Long.valueOf( id ), Integer.valueOf( prio ) );
}
br.close();
// write suspects to file
BufferedWriter bw = new BufferedWriter( new FileWriter( new File( args[1] ) ) );
for( String key : keys.keySet() )
{
TreeMap<Long,Integer> map = keys.get( key );
for( Long suspect : map.keySet() )
{
bw.write( suspect + " " + map.get( suspect ) + "\r\n" );
}
}
bw.close();
// if the osm-filter does not exist, write it
if ( osmFilter != null && !osmFilter.exists() )
{
bw = new BufferedWriter( new FileWriter( osmFilter ) );
bw.write( "<?xml version='1.0' encoding='UTF-8'?>\n" );
bw.write( "<osm version=\"0.6\">\n" );
for( String key : keys.keySet() )
{
TreeMap<Long,Integer> map = keys.get( key );
for( Long suspect : map.keySet() )
{
long id = suspect.longValue();
int ilon = (int) ( id >> 32 );
int ilat = (int) ( id & 0xffffffff );
double dlon = (ilon-180000000)/1000000.;
double dlat = (ilat-90000000)/1000000.;
bw.write( "<node id=\"" + id + "\" version=\"1\" timestamp=\"2017-01-10T12:00:00Z\" uid=\"1\" user=\"me\" changeset=\"1\" lat=\"" + dlat + "\" lon=\"" + dlon + "\"/>\n" );
}
}
bw.write( "</osm>\n" );
bw.close();
}
}
public static String getKey( int ilon, int ilat )
{
int lon = (ilon / 1000000 );
int lat = (ilat / 1000000 );
return "" + (100000 + lon*360 + lat);
}
}