Suspect-Manager: allow 999 days for resubmission, track neighbour resubmissions

This commit is contained in:
Arndt Brenschede 2022-07-17 11:38:28 +02:00
parent 08161b47fd
commit d5322667d5
3 changed files with 143 additions and 65 deletions

View file

@ -1,44 +1,27 @@
package btools.server;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;
import btools.mapaccess.OsmNode;
import btools.router.OsmNodeNamed;
import btools.router.OsmTrack;
import btools.router.RoutingContext;
import btools.router.RoutingEngine;
import btools.server.request.ProfileUploadHandler;
import btools.server.request.RequestHandler;
import btools.server.request.ServerHandler;
public class NearRecentWps
{
private static OsmNodeNamed[] recentWaypoints = new OsmNodeNamed[2000];
private static int nextRecentIndex = 0;
private OsmNodeNamed[] recentWaypoints = new OsmNodeNamed[2000];
private int nextRecentIndex = 0;
public static void add( List<OsmNodeNamed> wplist )
public void add( List<OsmNodeNamed> wplist )
{
synchronized( recentWaypoints )
{
for( OsmNodeNamed wp : wplist )
{
add( wp );
}
}
}
public void add( OsmNodeNamed wp )
{
recentWaypoints[nextRecentIndex++] = wp;
if ( nextRecentIndex >= recentWaypoints.length )
@ -46,24 +29,19 @@ public class NearRecentWps
nextRecentIndex = 0;
}
}
}
}
public static int count( long id )
public int count( long id )
{
int cnt = 0;
int ilon = (int) ( id >> 32 );
int ilat = (int) ( id & 0xffffffff );
OsmNode n = new OsmNode( id );
synchronized( recentWaypoints )
{
for ( int i=0; i<recentWaypoints.length; i++ )
{
OsmNodeNamed n = recentWaypoints[i];
if ( n != null )
OsmNodeNamed nn = recentWaypoints[i];
if ( nn != null )
{
int dlat = ilat - n.ilat;
int dlon = ilon - n.ilon;
if ( dlat > -29999 && dlat < 29999 && dlon > -39999 && dlon < 39999 )
if ( nn.calcDistance( n ) < 4000 )
{
cnt++;
}
@ -72,4 +50,29 @@ public class NearRecentWps
}
return cnt;
}
public OsmNodeNamed closest( long id )
{
int dmin = 0;
OsmNodeNamed nc = null;
OsmNode n = new OsmNode( id );
synchronized( recentWaypoints )
{
for ( int i=0; i<recentWaypoints.length; i++ )
{
OsmNodeNamed nn = recentWaypoints[i];
if ( nn != null )
{
int d = nn.calcDistance( n );
if ( d < 4000 && ( nc == null || d < dmin ) )
{
dmin = d;
nc = nn;
}
}
}
}
return nc;
}
}

View file

@ -240,7 +240,7 @@ public class RouteServer extends Thread implements Comparable<RouteServer>
if ( wplist.size() < 10 )
{
NearRecentWps.add( wplist );
SuspectManager.nearRecentWps.add( wplist );
}
for( Map.Entry<String,String> e : params.entrySet() )
{

View file

@ -11,12 +11,17 @@ import java.util.HashMap;
import java.util.StringTokenizer;
import java.util.TreeSet;
import btools.mapaccess.OsmNode;
import btools.router.OsmNodeNamed;
import btools.router.SuspectInfo;
public class SuspectManager extends Thread
{
private static SimpleDateFormat dfTimestampZ = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss" );
static NearRecentWps nearRecentWps = new NearRecentWps();
static NearRecentWps hiddenWps = new NearRecentWps();
private static String formatZ( Date date )
{
synchronized( dfTimestampZ )
@ -73,7 +78,7 @@ public class SuspectManager extends Thread
}
public static void newAndConfirmedJson( SuspectList suspects, BufferedWriter bw, String filter, int level ) throws IOException
public static void newAndConfirmedJson( SuspectList suspects, BufferedWriter bw, String filter, int level, Area polygon ) throws IOException
{
bw.write( "{\n" );
bw.write( "\"type\": \"FeatureCollection\",\n" );
@ -100,6 +105,11 @@ public class SuspectManager extends Thread
continue; // wrong false-positive state
}
if ( polygon != null && !polygon.isInBoundingBox( id ) )
{
continue; // not in selected polygon (pre-check)
}
String dueTime = null;
if ( !"deferred".equals( filter ) )
{
@ -132,6 +142,11 @@ public class SuspectManager extends Thread
dueTime = hideTime < 0 ? "(asap)" : formatAge( hideTime + 43200000 );
}
if ( polygon != null && !polygon.isInArea( id ) )
{
continue; // not in selected polygon
}
File confirmedEntry = new File( "confirmednegatives/" + id );
String status = suspects.newOrConfirmed[isuspect] ? "new" : "archived";
if ( confirmedEntry.exists() )
@ -186,7 +201,25 @@ public class SuspectManager extends Thread
public static void process( String url, BufferedWriter bw ) throws IOException
{
StringTokenizer tk = new StringTokenizer( url, "/" );
try
{
_process( url, bw );
}
catch( IllegalArgumentException iae )
{
try
{
bw.write( "<br><br>ERROR: " + iae.getMessage() + "<br><br>\n\n" );
bw.write( "(press Browser-Back to continue)\n" );
bw.flush();
}
catch (IOException _ignore){}
}
}
private static void _process( String url, BufferedWriter bw ) throws IOException
{
StringTokenizer tk = new StringTokenizer( url, "/?" );
tk.nextToken();
tk.nextToken();
long id = 0L;
@ -218,12 +251,26 @@ public class SuspectManager extends Thread
SuspectList suspects = getAllSuspects( suspectFilename );
Area polygon = null;
if ( !("/world".equals( country ) || "".equals( country ) ) )
{
File polyFile = new File( "worldpolys" + country + ".poly" );
if ( !polyFile.exists() )
{
bw.write( "polygon file for country '" + country + "' not found\n" );
bw.write( "</body></html>\n" );
bw.flush();
return;
}
polygon = new Area( polyFile );
}
if ( url.endsWith( ".json" ) )
{
StringTokenizer tk2 = new StringTokenizer( tk.nextToken(), "." );
int level = Integer.parseInt( tk2.nextToken() );
newAndConfirmedJson( suspects, bw, filter, level );
newAndConfirmedJson( suspects, bw, filter, level, polygon );
return;
}
@ -264,20 +311,6 @@ public class SuspectManager extends Thread
return;
}
Area polygon = null;
if ( !"/world".equals( country ) )
{
File polyFile = new File( "worldpolys" + country + ".poly" );
if ( !polyFile.exists() )
{
bw.write( "polygon file for country '" + country + "' not found\n" );
bw.write( "</body></html>\n" );
bw.flush();
return;
}
polygon = new Area( polyFile );
}
File suspectFile = new File( "worldsuspects.txt" );
if ( !suspectFile.exists() )
{
@ -365,10 +398,11 @@ public class SuspectManager extends Thread
String command = tk.nextToken();
if ( "falsepositive".equals( command ) )
{
int wps = NearRecentWps.count( id );
if ( wps < 0 ) // FIXME
int wps = nearRecentWps.count( id );
if ( wps < 8 )
{
message = "marking false-positive requires at least 8 recent nearby waypoints from BRouter-Web, found: " + wps;
message = "marking false-positive requires at least 8 recent nearby waypoints from BRouter-Web, found: " + wps
+ "<br><br>****** DO SOME MORE TEST-ROUTINGS IN BROUTER-WEB ******* before marking false positive";
}
else
{
@ -379,10 +413,11 @@ public class SuspectManager extends Thread
}
if ( "confirm".equals( command ) )
{
int wps = NearRecentWps.count( id );
int wps = nearRecentWps.count( id );
if ( wps < 2 )
{
message = "marking confirmed requires at least 2 recent nearby waypoints from BRouter-Web, found: " + wps;
message = "marking confirmed requires at least 2 recent nearby waypoints from BRouter-Web, found: " + wps
+ "<br><br>****** DO AT LEAST ONE TEST-ROUTING IN BROUTER-WEB ******* before marking confirmed";
}
else
{
@ -401,13 +436,34 @@ public class SuspectManager extends Thread
if ( tk.hasMoreTokens() )
{
String param = tk.nextToken();
if ( param.startsWith( "ndays=" ) )
{
param = param.substring( "ndays=".length() );
}
try
{
hideDays = Integer.parseInt( param ); // hiding, not fixing
}
catch( NumberFormatException nfe )
{
throw new IllegalArgumentException( "not a number: " + param );
}
if ( hideDays < 1 || hideDays > 999 )
{
throw new IllegalArgumentException( "hideDays must be within 1..999" );
}
message = "Hide issue " + id + " for " + hideDays + " days";
}
else
{
message = "Marked issue " + id + " as fixed";
}
if ( hideDays > 0 )
{
OsmNodeNamed nn = new OsmNodeNamed ( new OsmNode( id ) );
nn.name = "" + hideDays;
hiddenWps.add( nn );
}
id = 0L;
fixedMarker.setLastModified( System.currentTimeMillis() + hideDays*86400000L );
}
@ -432,6 +488,11 @@ public class SuspectManager extends Thread
// get triggers
int triggers = suspects.trigger4Id( id );
SuspectList daily = getDailySuspectsIfLoaded();
if ( daily != null && daily != suspects )
{
triggers |= daily.trigger4Id( id ); // hack, because osmoscope does not echo type of analysis
}
String triggerText = SuspectInfo.getTriggerText( triggers );
@ -484,6 +545,11 @@ public class SuspectManager extends Thread
{
String prefix = "<a href=\"/brouter/suspects" + countryId + "/fixed";
String prefix2 = " &nbsp;&nbsp;" + prefix;
OsmNodeNamed nc = hiddenWps.closest( id );
String proposal = nc == null ? "" : nc.name;
String prefix2d = "<form action=\"/brouter/suspects" + countryId + "/fixed\" method=\"get\">hide for days: &nbsp;&nbsp;<input type=\"text\" name=\"ndays\" value=\"" + proposal + "\" autofocus><button type=\"submit\">OK</button></form>";
bw.write( prefix + "\">mark as fixed</a><br><br>\n" );
bw.write( "hide for: weeks:" );
bw.write( prefix2 + "/7\">1w</a>" );
@ -496,6 +562,7 @@ public class SuspectManager extends Thread
bw.write( prefix2 + "/122\">4m</a>" );
bw.write( prefix2 + "/152\">5m</a>" );
bw.write( prefix2 + "/183\">6m</a><br><br>\n" );
bw.write( prefix2d + "<br><br>\n" );
}
else
{
@ -625,6 +692,14 @@ public class SuspectManager extends Thread
private static HashMap<String,SuspectList> allSuspectsMap = new HashMap<String,SuspectList>();
private static SuspectList getDailySuspectsIfLoaded() throws IOException
{
synchronized( allSuspectsMap )
{
return allSuspectsMap.get( "dailysuspects.txt" );
}
}
private static SuspectList getAllSuspects( String suspectFileName ) throws IOException
{
synchronized( allSuspectsMap )