suspect manager
This commit is contained in:
parent
45495d8692
commit
c9593331bd
3 changed files with 384 additions and 0 deletions
|
@ -0,0 +1,75 @@
|
||||||
|
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.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;
|
||||||
|
|
||||||
|
public static void add( List<OsmNodeNamed> wplist )
|
||||||
|
{
|
||||||
|
synchronized( recentWaypoints )
|
||||||
|
{
|
||||||
|
for( OsmNodeNamed wp : wplist )
|
||||||
|
{
|
||||||
|
recentWaypoints[nextRecentIndex++] = wp;
|
||||||
|
if ( nextRecentIndex >= recentWaypoints.length )
|
||||||
|
{
|
||||||
|
nextRecentIndex = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int count( long id )
|
||||||
|
{
|
||||||
|
int cnt = 0;
|
||||||
|
int ilon = (int) ( id >> 32 );
|
||||||
|
int ilat = (int) ( id & 0xffffffff );
|
||||||
|
synchronized( recentWaypoints )
|
||||||
|
{
|
||||||
|
for ( int i=0; i<recentWaypoints.length; i++ )
|
||||||
|
{
|
||||||
|
OsmNodeNamed n = recentWaypoints[i];
|
||||||
|
if ( n != null )
|
||||||
|
{
|
||||||
|
int dlat = ilat - n.ilat;
|
||||||
|
int dlon = ilon - n.ilon;
|
||||||
|
if ( dlat > -29999 && dlat < 29999 && dlon > -39999 && dlon < 39999 )
|
||||||
|
{
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
}
|
|
@ -112,6 +112,12 @@ public class RouteServer extends Thread
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ( url.startsWith( "/brouter/suspects" ) )
|
||||||
|
{
|
||||||
|
writeHttpHeader(bw, "text/html");
|
||||||
|
SuspectManager.process( url, bw );
|
||||||
|
return;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException( "unknown request syntax: " + getline );
|
throw new IllegalArgumentException( "unknown request syntax: " + getline );
|
||||||
|
@ -119,6 +125,11 @@ public class RouteServer extends Thread
|
||||||
RoutingContext rc = handler.readRoutingContext();
|
RoutingContext rc = handler.readRoutingContext();
|
||||||
List<OsmNodeNamed> wplist = handler.readWayPointList();
|
List<OsmNodeNamed> wplist = handler.readWayPointList();
|
||||||
|
|
||||||
|
if ( wplist.size() < 10 )
|
||||||
|
{
|
||||||
|
NearRecentWps.add( wplist );
|
||||||
|
}
|
||||||
|
|
||||||
cr = new RoutingEngine( null, null, serviceContext.segmentDir, wplist, rc );
|
cr = new RoutingEngine( null, null, serviceContext.segmentDir, wplist, rc );
|
||||||
cr.quite = true;
|
cr.quite = true;
|
||||||
cr.doRun( maxRunningTime );
|
cr.doRun( maxRunningTime );
|
||||||
|
|
298
brouter-server/src/main/java/btools/server/SuspectManager.java
Normal file
298
brouter-server/src/main/java/btools/server/SuspectManager.java
Normal file
|
@ -0,0 +1,298 @@
|
||||||
|
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.util.StringTokenizer;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
|
public class SuspectManager extends Thread
|
||||||
|
{
|
||||||
|
private static String formatAge( File f )
|
||||||
|
{
|
||||||
|
long age = System.currentTimeMillis() - f.lastModified();
|
||||||
|
long minutes = age / 60000;
|
||||||
|
if ( minutes < 60 )
|
||||||
|
{
|
||||||
|
return minutes + " minutes";
|
||||||
|
}
|
||||||
|
long hours = minutes / 60;
|
||||||
|
if ( hours < 24 )
|
||||||
|
{
|
||||||
|
return hours + " hours";
|
||||||
|
}
|
||||||
|
long days = hours / 24;
|
||||||
|
return days + " days";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getLevelDecsription( int level )
|
||||||
|
{
|
||||||
|
switch( level )
|
||||||
|
{
|
||||||
|
case 30 : return "motorway";
|
||||||
|
case 28 : return "trunk";
|
||||||
|
case 26 : return "primary";
|
||||||
|
case 24 : return "secondary";
|
||||||
|
case 22 : return "tertiary";
|
||||||
|
default: return "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void process( String url, BufferedWriter bw ) throws IOException
|
||||||
|
{
|
||||||
|
bw.write( "<html><body>\n" );
|
||||||
|
|
||||||
|
StringTokenizer tk = new StringTokenizer( url, "/" );
|
||||||
|
tk.nextToken();
|
||||||
|
tk.nextToken();
|
||||||
|
long id = 0L;
|
||||||
|
String country = null;
|
||||||
|
|
||||||
|
if ( tk.hasMoreTokens() )
|
||||||
|
{
|
||||||
|
String ctry = tk.nextToken();
|
||||||
|
if ( new File( "suspects/suspects_" + ctry + ".txt" ).exists() )
|
||||||
|
{
|
||||||
|
country = ctry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( country == null ) // generate country list
|
||||||
|
{
|
||||||
|
File[] files = new File( "suspects" ).listFiles();
|
||||||
|
TreeSet<String> names = new TreeSet<String>();
|
||||||
|
for ( File f : files )
|
||||||
|
{
|
||||||
|
String name = f.getName();
|
||||||
|
if ( name.startsWith( "suspects_" ) && name.endsWith( ".txt" ) )
|
||||||
|
{
|
||||||
|
names.add( name.substring( 9, name.length() - 4 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for ( String ctry : names )
|
||||||
|
{
|
||||||
|
String url2 = "/brouter/suspects/" + ctry;
|
||||||
|
bw.write( "<a href=\"" + url2 + "\">" + ctry + "</a><br>\n" );
|
||||||
|
}
|
||||||
|
bw.write( "</body></html>\n" );
|
||||||
|
bw.flush();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean showWatchList = false;
|
||||||
|
if ( tk.hasMoreTokens() )
|
||||||
|
{
|
||||||
|
String t = tk.nextToken();
|
||||||
|
if ( "watchlist".equals( t ) )
|
||||||
|
{
|
||||||
|
showWatchList = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
id = Long.parseLong( t );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( showWatchList )
|
||||||
|
{
|
||||||
|
File suspects = new File( "suspects/suspects_" + country + ".txt" );
|
||||||
|
bw.write( "watchlist for " + country + "\n" );
|
||||||
|
bw.write( "<br><a href=\"/brouter/suspects\">back to country list</a><br><br>\n" );
|
||||||
|
if ( suspects.exists() )
|
||||||
|
{
|
||||||
|
BufferedReader r = new BufferedReader( new FileReader( suspects ) );
|
||||||
|
for ( ;; )
|
||||||
|
{
|
||||||
|
String line = r.readLine();
|
||||||
|
if ( line == null )
|
||||||
|
break;
|
||||||
|
StringTokenizer tk2 = new StringTokenizer( line );
|
||||||
|
id = Long.parseLong( tk2.nextToken() );
|
||||||
|
String countryId = country + "/" + id;
|
||||||
|
|
||||||
|
if ( new File( "falsepositives/" + id ).exists() )
|
||||||
|
{
|
||||||
|
continue; // known false positive
|
||||||
|
}
|
||||||
|
File fixedEntry = new File( "fixedsuspects/" + id );
|
||||||
|
File confirmedEntry = new File( "confirmednegatives/" + id );
|
||||||
|
if ( !( fixedEntry.exists() && confirmedEntry.exists() ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
long age = System.currentTimeMillis() - confirmedEntry.lastModified();
|
||||||
|
if ( age / 1000 < 3600 * 24 * 8 )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String hint = " confirmed " + formatAge( confirmedEntry ) + " ago";
|
||||||
|
int ilon = (int) ( id >> 32 );
|
||||||
|
int ilat = (int) ( id & 0xffffffff );
|
||||||
|
double dlon = ( ilon - 180000000 ) / 1000000.;
|
||||||
|
double dlat = ( ilat - 90000000 ) / 1000000.;
|
||||||
|
String url2 = "/brouter/suspects/" + countryId;
|
||||||
|
bw.write( "<a href=\"" + url2 + "\">" + dlon + "," + dlat + "</a>" + hint + "<br>\n" );
|
||||||
|
}
|
||||||
|
r.close();
|
||||||
|
}
|
||||||
|
bw.write( "</body></html>\n" );
|
||||||
|
bw.flush();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String message = null;
|
||||||
|
if ( tk.hasMoreTokens() )
|
||||||
|
{
|
||||||
|
String command = tk.nextToken();
|
||||||
|
if ( "falsepositive".equals( command ) )
|
||||||
|
{
|
||||||
|
int wps = NearRecentWps.count( id );
|
||||||
|
if ( wps < 8 )
|
||||||
|
{
|
||||||
|
message = "marking false-positive requires at least 10 recent nearby waypoints from BRouter-Web, found: " + wps;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new File( "falsepositives/" + id ).createNewFile();
|
||||||
|
id = 0L;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( "confirm".equals( command ) )
|
||||||
|
{
|
||||||
|
int wps = NearRecentWps.count( id );
|
||||||
|
if ( wps < 2 )
|
||||||
|
{
|
||||||
|
message = "marking confirmed requires at least 2 recent nearby waypoints from BRouter-Web, found: " + wps;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new File( "confirmednegatives/" + id ).createNewFile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( "fixed".equals( command ) )
|
||||||
|
{
|
||||||
|
new File( "fixedsuspects/" + id ).createNewFile();
|
||||||
|
id = 0L;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( id != 0L )
|
||||||
|
{
|
||||||
|
String countryId = country + "/" + id;
|
||||||
|
|
||||||
|
int ilon = (int) ( id >> 32 );
|
||||||
|
int ilat = (int) ( id & 0xffffffff );
|
||||||
|
double dlon = ( ilon - 180000000 ) / 1000000.;
|
||||||
|
double dlat = ( ilat - 90000000 ) / 1000000.;
|
||||||
|
|
||||||
|
String url1 = "http://brouter.de/brouter-web/#zoom=18&lat=" + dlat + "&lon=" + dlon
|
||||||
|
+ "&layer=OpenStreetMap&lonlats=" + dlon + "," + dlat + "&profile=car-eco-de";
|
||||||
|
|
||||||
|
// String url1 = "http://localhost:8080/brouter-web/#map=18/" + dlat + "/"
|
||||||
|
// + dlon + "/Mapsforge Tile Server&lonlats=" + dlon + "," + dlat;
|
||||||
|
|
||||||
|
String url2 = "https://www.openstreetmap.org/?mlat=" + dlat + "&mlon=" + dlon + "#map=19/" + dlat + "/" + dlon + "&layers=N";
|
||||||
|
|
||||||
|
double slon = 0.00156;
|
||||||
|
double slat = 0.001;
|
||||||
|
String url3 = "http://osmose.openstreetmap.fr/de/josm_proxy?load_and_zoom?left=" + ( dlon - slon )
|
||||||
|
+ "&bottom=" + ( dlat - slat ) + "&right=" + ( dlon + slon ) + "&top=" + ( dlat + slat );
|
||||||
|
|
||||||
|
if ( message != null )
|
||||||
|
{
|
||||||
|
bw.write( "<strong>" + message + "</strong><br><br>\n" );
|
||||||
|
}
|
||||||
|
bw.write( "<a href=\"" + url1 + "\">Open in BRouter-Web</a><br><br>\n" );
|
||||||
|
bw.write( "<a href=\"" + url2 + "\">Open in OpenStreetmap</a><br><br>\n" );
|
||||||
|
bw.write( "<a href=\"" + url3 + "\">Open in JOSM (via remote control)</a><br><br>\n" );
|
||||||
|
File fixedEntry = new File( "fixedsuspects/" + id );
|
||||||
|
if ( fixedEntry.exists() )
|
||||||
|
{
|
||||||
|
bw.write( "<br><br><a href=\"/brouter/suspects/" + country + "/watchlist\">back to watchlist</a><br><br>\n" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bw.write( "<a href=\"/brouter/suspects/" + countryId + "/falsepositive\">mark false positive (=not an issue)</a><br><br>\n" );
|
||||||
|
File confirmedEntry = new File( "confirmednegatives/" + id );
|
||||||
|
if ( confirmedEntry.exists() )
|
||||||
|
{
|
||||||
|
bw.write( "<a href=\"/brouter/suspects/" + countryId + "/fixed\">mark as fixed</a><br><br>\n" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bw.write( "<a href=\"/brouter/suspects/" + countryId + "/confirm\">mark as a confirmed issue</a><br><br>\n" );
|
||||||
|
}
|
||||||
|
bw.write( "<br><br><a href=\"/brouter/suspects/" + country + "\">back to issue list</a><br><br>\n" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
File suspects = new File( "suspects/suspects_" + country + ".txt" );
|
||||||
|
bw.write( "suspect list for " + country + "\n" );
|
||||||
|
bw.write( "<br><a href=\"/brouter/suspects/" + country + "/watchlist\">see watchlist</a>\n" );
|
||||||
|
bw.write( "<br><a href=\"/brouter/suspects\">back to country list</a><br><br>\n" );
|
||||||
|
if ( suspects.exists() )
|
||||||
|
{
|
||||||
|
int maxprio = 0;
|
||||||
|
for ( int pass = 1; pass <= 2; pass++ )
|
||||||
|
{
|
||||||
|
if ( pass == 2 )
|
||||||
|
{
|
||||||
|
bw.write( "current level: " + getLevelDecsription( maxprio ) + "<br><br>\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferedReader r = new BufferedReader( new FileReader( suspects ) );
|
||||||
|
for ( ;; )
|
||||||
|
{
|
||||||
|
String line = r.readLine();
|
||||||
|
if ( line == null )
|
||||||
|
break;
|
||||||
|
StringTokenizer tk2 = new StringTokenizer( line );
|
||||||
|
id = Long.parseLong( tk2.nextToken() );
|
||||||
|
int prio = Integer.parseInt( tk2.nextToken() );
|
||||||
|
prio = ( ( prio + 1 ) / 2 ) * 2; // normalize (no link prios)
|
||||||
|
String countryId = country + "/" + id;
|
||||||
|
|
||||||
|
String hint = "";
|
||||||
|
|
||||||
|
if ( new File( "falsepositives/" + id ).exists() )
|
||||||
|
{
|
||||||
|
continue; // known false positive
|
||||||
|
}
|
||||||
|
if ( new File( "fixedsuspects/" + id ).exists() )
|
||||||
|
{
|
||||||
|
continue; // known fixed
|
||||||
|
}
|
||||||
|
if ( pass == 1 )
|
||||||
|
{
|
||||||
|
if ( prio > maxprio )
|
||||||
|
maxprio = prio;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( prio < maxprio )
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
File confirmedEntry = new File( "confirmednegatives/" + id );
|
||||||
|
if ( confirmedEntry.exists() )
|
||||||
|
{
|
||||||
|
hint = " confirmed " + formatAge( confirmedEntry ) + " ago";
|
||||||
|
}
|
||||||
|
int ilon = (int) ( id >> 32 );
|
||||||
|
int ilat = (int) ( id & 0xffffffff );
|
||||||
|
double dlon = ( ilon - 180000000 ) / 1000000.;
|
||||||
|
double dlat = ( ilat - 90000000 ) / 1000000.;
|
||||||
|
String url2 = "/brouter/suspects/" + countryId;
|
||||||
|
bw.write( "<a href=\"" + url2 + "\">" + dlon + "," + dlat + "</a>" + hint + "<br>\n" );
|
||||||
|
}
|
||||||
|
r.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bw.write( "</body></html>\n" );
|
||||||
|
bw.flush();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue