refactored waypoint-matching into map-access-layer
This commit is contained in:
parent
02b8202001
commit
9e64eb39c4
6 changed files with 148 additions and 129 deletions
|
@ -15,6 +15,15 @@ public class OsmNodeNamed extends OsmNode
|
||||||
public double nogoWeight; // weight for nogopoint
|
public double nogoWeight; // weight for nogopoint
|
||||||
public boolean isNogo = false;
|
public boolean isNogo = false;
|
||||||
|
|
||||||
|
public OsmNodeNamed()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public OsmNodeNamed( OsmNode n)
|
||||||
|
{
|
||||||
|
super( n.ilon, n.ilat );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,13 +16,13 @@ import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import btools.mapaccess.MatchedWaypoint;
|
||||||
import btools.mapaccess.OsmPos;
|
import btools.mapaccess.OsmPos;
|
||||||
import btools.util.CompactLongMap;
|
import btools.util.CompactLongMap;
|
||||||
import btools.util.FrozenLongMap;
|
import btools.util.FrozenLongMap;
|
||||||
|
|
|
@ -10,18 +10,17 @@ import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import btools.mapaccess.MatchedWaypoint;
|
||||||
import btools.mapaccess.NodesCache;
|
import btools.mapaccess.NodesCache;
|
||||||
import btools.mapaccess.OsmLink;
|
import btools.mapaccess.OsmLink;
|
||||||
import btools.mapaccess.OsmLinkHolder;
|
import btools.mapaccess.OsmLinkHolder;
|
||||||
import btools.mapaccess.OsmNode;
|
import btools.mapaccess.OsmNode;
|
||||||
import btools.mapaccess.OsmNodePairSet;
|
import btools.mapaccess.OsmNodePairSet;
|
||||||
import btools.mapaccess.OsmNodesMap;
|
|
||||||
import btools.util.SortedHeap;
|
import btools.util.SortedHeap;
|
||||||
import btools.util.StackSampler;
|
import btools.util.StackSampler;
|
||||||
|
|
||||||
public class RoutingEngine extends Thread
|
public class RoutingEngine extends Thread
|
||||||
{
|
{
|
||||||
private OsmNodesMap nodesMap;
|
|
||||||
private NodesCache nodesCache;
|
private NodesCache nodesCache;
|
||||||
private SortedHeap<OsmPath> openSet = new SortedHeap<OsmPath>();
|
private SortedHeap<OsmPath> openSet = new SortedHeap<OsmPath>();
|
||||||
private boolean finished = false;
|
private boolean finished = false;
|
||||||
|
@ -326,7 +325,6 @@ public class RoutingEngine extends Thread
|
||||||
|
|
||||||
public void cleanOnOOM()
|
public void cleanOnOOM()
|
||||||
{
|
{
|
||||||
nodesMap = null;
|
|
||||||
terminate();
|
terminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,6 +383,7 @@ public class RoutingEngine extends Thread
|
||||||
{
|
{
|
||||||
MatchedWaypoint mwp = new MatchedWaypoint();
|
MatchedWaypoint mwp = new MatchedWaypoint();
|
||||||
mwp.waypoint = waypoints.get(i);
|
mwp.waypoint = waypoints.get(i);
|
||||||
|
mwp.name = waypoints.get(i).name;
|
||||||
matchedWaypoints.add( mwp );
|
matchedWaypoints.add( mwp );
|
||||||
}
|
}
|
||||||
matchWaypointsToNodes( matchedWaypoints );
|
matchWaypointsToNodes( matchedWaypoints );
|
||||||
|
@ -452,46 +451,9 @@ public class RoutingEngine extends Thread
|
||||||
private void matchWaypointsToNodes( List<MatchedWaypoint> unmatchedWaypoints )
|
private void matchWaypointsToNodes( List<MatchedWaypoint> unmatchedWaypoints )
|
||||||
{
|
{
|
||||||
resetCache( false );
|
resetCache( false );
|
||||||
nodesCache.waypointMatcher = new WaypointMatcherImpl( unmatchedWaypoints, 250., islandNodePairs );
|
nodesCache.matchWaypointsToNodes( unmatchedWaypoints, 250., islandNodePairs );
|
||||||
for( MatchedWaypoint mwp : unmatchedWaypoints )
|
|
||||||
{
|
|
||||||
preloadPosition( mwp.waypoint );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( nodesCache.first_file_access_failed )
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException( "datafile " + nodesCache.first_file_access_name + " not found" );
|
|
||||||
}
|
|
||||||
for( MatchedWaypoint mwp : unmatchedWaypoints )
|
|
||||||
{
|
|
||||||
if ( mwp.crosspoint == null )
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException( mwp.waypoint.name + "-position not mapped in existing datafile" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void preloadPosition( OsmNode n )
|
|
||||||
{
|
|
||||||
int d = 12500;
|
|
||||||
nodesCache.first_file_access_failed = false;
|
|
||||||
nodesCache.first_file_access_name = null;
|
|
||||||
nodesCache.loadSegmentFor( n.ilon, n.ilat );
|
|
||||||
if ( nodesCache.first_file_access_failed )
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException( "datafile " + nodesCache.first_file_access_name + " not found" );
|
|
||||||
}
|
|
||||||
for( int idxLat=-1; idxLat<=1; idxLat++ )
|
|
||||||
for( int idxLon=-1; idxLon<=1; idxLon++ )
|
|
||||||
{
|
|
||||||
if ( idxLon != 0 || idxLat != 0 )
|
|
||||||
{
|
|
||||||
nodesCache.loadSegmentFor( n.ilon + d*idxLon , n.ilat +d*idxLat );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private OsmTrack searchTrack( MatchedWaypoint startWp, MatchedWaypoint endWp, OsmTrack nearbyTrack, OsmTrack refTrack )
|
private OsmTrack searchTrack( MatchedWaypoint startWp, MatchedWaypoint endWp, OsmTrack nearbyTrack, OsmTrack refTrack )
|
||||||
{
|
{
|
||||||
OsmTrack track = null;
|
OsmTrack track = null;
|
||||||
|
@ -613,30 +575,15 @@ public class RoutingEngine extends Thread
|
||||||
{
|
{
|
||||||
logInfo( "NodesCache status before reset=" + nodesCache.formatStatus() );
|
logInfo( "NodesCache status before reset=" + nodesCache.formatStatus() );
|
||||||
}
|
}
|
||||||
nodesMap = new OsmNodesMap();
|
|
||||||
|
|
||||||
long maxmem = routingContext.memoryclass * 131072L; // 1/8 of total
|
long maxmem = routingContext.memoryclass * 131072L; // 1/8 of total
|
||||||
|
|
||||||
nodesCache = new NodesCache(segmentDir, nodesMap, routingContext.expctxWay, routingContext.forceSecondaryData, maxmem, nodesCache, detailed );
|
nodesCache = new NodesCache(segmentDir, routingContext.expctxWay, routingContext.forceSecondaryData, maxmem, nodesCache, detailed );
|
||||||
islandNodePairs.clearTempPairs();
|
islandNodePairs.clearTempPairs();
|
||||||
}
|
}
|
||||||
|
|
||||||
private OsmNode getStartNode( long startId )
|
|
||||||
{
|
|
||||||
// initialize the start-node
|
|
||||||
OsmNode start = new OsmNode( startId );
|
|
||||||
start.setHollow();
|
|
||||||
if ( !nodesCache.obtainNonHollowNode( start ) )
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
nodesCache.expandHollowLinkTargets( start );
|
|
||||||
return start;
|
|
||||||
}
|
|
||||||
|
|
||||||
private OsmPath getStartPath( OsmNode n1, OsmNode n2, MatchedWaypoint mwp, OsmNodeNamed endPos, boolean sameSegmentSearch )
|
private OsmPath getStartPath( OsmNode n1, OsmNode n2, MatchedWaypoint mwp, OsmNodeNamed endPos, boolean sameSegmentSearch )
|
||||||
{
|
{
|
||||||
OsmPath p = getStartPath( n1, n2, mwp.waypoint, endPos );
|
OsmPath p = getStartPath( n1, n2, new OsmNodeNamed( mwp.waypoint ), endPos );
|
||||||
|
|
||||||
// special case: start+end on same segment
|
// special case: start+end on same segment
|
||||||
if ( sameSegmentSearch )
|
if ( sameSegmentSearch )
|
||||||
|
@ -680,7 +627,7 @@ public class RoutingEngine extends Thread
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private OsmPath getStartPath( OsmNode n1, OsmNode n2, OsmNodeNamed wp, OsmNode endPos )
|
private OsmPath getStartPath( OsmNode n1, OsmNode n2, OsmNodeNamed wp, OsmNodeNamed endPos )
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -775,12 +722,12 @@ public class RoutingEngine extends Thread
|
||||||
long startNodeId1 = startWp.node1.getIdFromPos();
|
long startNodeId1 = startWp.node1.getIdFromPos();
|
||||||
long startNodeId2 = startWp.node2.getIdFromPos();
|
long startNodeId2 = startWp.node2.getIdFromPos();
|
||||||
|
|
||||||
OsmNodeNamed endPos = endWp == null ? null : endWp.crosspoint;
|
OsmNodeNamed endPos = endWp == null ? null : new OsmNodeNamed( endWp.crosspoint );
|
||||||
|
|
||||||
boolean sameSegmentSearch = ( startNodeId1 == endNodeId1 && startNodeId2 == endNodeId2 )
|
boolean sameSegmentSearch = ( startNodeId1 == endNodeId1 && startNodeId2 == endNodeId2 )
|
||||||
|| ( startNodeId1 == endNodeId2 && startNodeId2 == endNodeId1 );
|
|| ( startNodeId1 == endNodeId2 && startNodeId2 == endNodeId1 );
|
||||||
|
|
||||||
OsmNode start1 = getStartNode( startNodeId1 );
|
OsmNode start1 = nodesCache.getStartNode( startNodeId1 );
|
||||||
if ( start1 == null ) return null;
|
if ( start1 == null ) return null;
|
||||||
OsmNode start2 = null;
|
OsmNode start2 = null;
|
||||||
for( OsmLink link = start1.firstlink; link != null; link = link.getNext( start1 ) )
|
for( OsmLink link = start1.firstlink; link != null; link = link.getNext( start1 ) )
|
||||||
|
@ -793,11 +740,6 @@ public class RoutingEngine extends Thread
|
||||||
}
|
}
|
||||||
if ( start2 == null ) return null;
|
if ( start2 == null ) return null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if ( start1 == null || start2 == null ) return null;
|
|
||||||
|
|
||||||
routingContext.startDirectionValid = routingContext.forceUseStartDirection || fastPartialRecalc;
|
routingContext.startDirectionValid = routingContext.forceUseStartDirection || fastPartialRecalc;
|
||||||
routingContext.startDirectionValid &= routingContext.startDirection != null && !routingContext.inverseDirection;
|
routingContext.startDirectionValid &= routingContext.startDirection != null && !routingContext.inverseDirection;
|
||||||
if ( routingContext.startDirectionValid )
|
if ( routingContext.startDirectionValid )
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
*
|
*
|
||||||
* @author ab
|
* @author ab
|
||||||
*/
|
*/
|
||||||
package btools.router;
|
package btools.mapaccess;
|
||||||
|
|
||||||
import java.io.DataInput;
|
import java.io.DataInput;
|
||||||
import java.io.DataOutput;
|
import java.io.DataOutput;
|
||||||
|
@ -11,13 +11,15 @@ import java.io.IOException;
|
||||||
|
|
||||||
import btools.mapaccess.OsmNode;
|
import btools.mapaccess.OsmNode;
|
||||||
|
|
||||||
final class MatchedWaypoint
|
public final class MatchedWaypoint
|
||||||
{
|
{
|
||||||
public OsmNode node1;
|
public OsmNode node1;
|
||||||
public OsmNode node2;
|
public OsmNode node2;
|
||||||
public OsmNodeNamed crosspoint;
|
public OsmNode crosspoint;
|
||||||
public OsmNodeNamed waypoint;
|
public OsmNode waypoint;
|
||||||
public double radius; // radius in meters
|
public String name; // waypoint name used in error messages
|
||||||
|
public double radius; // distance in meter between waypoint and crosspoint
|
||||||
|
|
||||||
public boolean hasUpdate;
|
public boolean hasUpdate;
|
||||||
|
|
||||||
public void writeToStream( DataOutput dos ) throws IOException
|
public void writeToStream( DataOutput dos ) throws IOException
|
||||||
|
@ -38,8 +40,8 @@ final class MatchedWaypoint
|
||||||
MatchedWaypoint mwp = new MatchedWaypoint();
|
MatchedWaypoint mwp = new MatchedWaypoint();
|
||||||
mwp.node1 = new OsmNode();
|
mwp.node1 = new OsmNode();
|
||||||
mwp.node2 = new OsmNode();
|
mwp.node2 = new OsmNode();
|
||||||
mwp.crosspoint = new OsmNodeNamed();
|
mwp.crosspoint = new OsmNode();
|
||||||
mwp.waypoint = new OsmNodeNamed();
|
mwp.waypoint = new OsmNode();
|
||||||
|
|
||||||
mwp.node1.ilat = dis.readInt();
|
mwp.node1.ilat = dis.readInt();
|
||||||
mwp.node1.ilon = dis.readInt();
|
mwp.node1.ilon = dis.readInt();
|
|
@ -8,6 +8,7 @@ package btools.mapaccess;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import btools.codec.DataBuffers;
|
import btools.codec.DataBuffers;
|
||||||
import btools.codec.MicroCache;
|
import btools.codec.MicroCache;
|
||||||
|
@ -53,10 +54,10 @@ public final class NodesCache
|
||||||
return "collecting=" + garbageCollectionEnabled + " noGhosts=" + ghostCleaningDone + " cacheSum=" + cacheSum + " cacheSumClean=" + cacheSumClean + " ghostSum=" + ghostSum + " ghostWakeup=" + ghostWakeup ;
|
return "collecting=" + garbageCollectionEnabled + " noGhosts=" + ghostCleaningDone + " cacheSum=" + cacheSum + " cacheSumClean=" + cacheSumClean + " ghostSum=" + ghostSum + " ghostWakeup=" + ghostWakeup ;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NodesCache( String segmentDir, OsmNodesMap nodesMap, BExpressionContextWay ctxWay, boolean forceSecondaryData, long maxmem, NodesCache oldCache, boolean detailed )
|
public NodesCache( String segmentDir, BExpressionContextWay ctxWay, boolean forceSecondaryData, long maxmem, NodesCache oldCache, boolean detailed )
|
||||||
{
|
{
|
||||||
this.segmentDir = new File( segmentDir );
|
this.segmentDir = new File( segmentDir );
|
||||||
this.nodesMap = nodesMap;
|
this.nodesMap = new OsmNodesMap();
|
||||||
this.expCtxWay = ctxWay;
|
this.expCtxWay = ctxWay;
|
||||||
this.lookupVersion = ctxWay.meta.lookupVersion;
|
this.lookupVersion = ctxWay.meta.lookupVersion;
|
||||||
this.lookupMinorVersion = ctxWay.meta.lookupMinorVersion;
|
this.lookupMinorVersion = ctxWay.meta.lookupMinorVersion;
|
||||||
|
@ -275,6 +276,71 @@ public final class NodesCache
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get a node for the given id with all link-targets also non-hollow
|
||||||
|
*
|
||||||
|
* It is required that an instance of the start-node does not yet
|
||||||
|
* exist, not even a hollow instance, so getStartNode should only
|
||||||
|
* be called once right after resetting the cache
|
||||||
|
*
|
||||||
|
* @param id the id of the node to load
|
||||||
|
*
|
||||||
|
* @return the fully expanded node for id, or null if it was not found
|
||||||
|
*/
|
||||||
|
public OsmNode getStartNode( long id )
|
||||||
|
{
|
||||||
|
// initialize the start-node
|
||||||
|
OsmNode n = new OsmNode( id );
|
||||||
|
n.setHollow();
|
||||||
|
if ( !obtainNonHollowNode( n ) )
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
expandHollowLinkTargets( n );
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void matchWaypointsToNodes( List<MatchedWaypoint> unmatchedWaypoints, double maxDistance, OsmNodePairSet islandNodePairs )
|
||||||
|
{
|
||||||
|
waypointMatcher = new WaypointMatcherImpl( unmatchedWaypoints, 250., islandNodePairs );
|
||||||
|
for( MatchedWaypoint mwp : unmatchedWaypoints )
|
||||||
|
{
|
||||||
|
preloadPosition( mwp.waypoint );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( first_file_access_failed )
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException( "datafile " + first_file_access_name + " not found" );
|
||||||
|
}
|
||||||
|
for( MatchedWaypoint mwp : unmatchedWaypoints )
|
||||||
|
{
|
||||||
|
if ( mwp.crosspoint == null )
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException( mwp.name + "-position not mapped in existing datafile" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void preloadPosition( OsmNode n )
|
||||||
|
{
|
||||||
|
int d = 12500;
|
||||||
|
first_file_access_failed = false;
|
||||||
|
first_file_access_name = null;
|
||||||
|
loadSegmentFor( n.ilon, n.ilat );
|
||||||
|
if ( first_file_access_failed )
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException( "datafile " + first_file_access_name + " not found" );
|
||||||
|
}
|
||||||
|
for( int idxLat=-1; idxLat<=1; idxLat++ )
|
||||||
|
for( int idxLon=-1; idxLon<=1; idxLon++ )
|
||||||
|
{
|
||||||
|
if ( idxLon != 0 || idxLat != 0 )
|
||||||
|
{
|
||||||
|
loadSegmentFor( n.ilon + d*idxLon , n.ilat +d*idxLat );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private OsmFile fileForSegment( int lonDegree, int latDegree ) throws Exception
|
private OsmFile fileForSegment( int lonDegree, int latDegree ) throws Exception
|
||||||
{
|
{
|
||||||
int lonMod5 = lonDegree % 5;
|
int lonMod5 = lonDegree % 5;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package btools.router;
|
package btools.mapaccess;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ public final class WaypointMatcherImpl implements WaypointMatcher
|
||||||
|
|
||||||
for ( MatchedWaypoint mwp : waypoints )
|
for ( MatchedWaypoint mwp : waypoints )
|
||||||
{
|
{
|
||||||
OsmNodeNamed wp = mwp.waypoint;
|
OsmNode wp = mwp.waypoint;
|
||||||
|
|
||||||
double x1 = ( lon1 - wp.ilon ) * dlon2m;
|
double x1 = ( lon1 - wp.ilon ) * dlon2m;
|
||||||
double y1 = ( lat1 - wp.ilat ) * dlat2m;
|
double y1 = ( lat1 - wp.ilat ) * dlat2m;
|
||||||
|
@ -86,7 +86,7 @@ public final class WaypointMatcherImpl implements WaypointMatcher
|
||||||
anyUpdate = true;
|
anyUpdate = true;
|
||||||
// calculate crosspoint
|
// calculate crosspoint
|
||||||
if ( mwp.crosspoint == null )
|
if ( mwp.crosspoint == null )
|
||||||
mwp.crosspoint = new OsmNodeNamed();
|
mwp.crosspoint = new OsmNode();
|
||||||
if ( s2 < 0. )
|
if ( s2 < 0. )
|
||||||
{
|
{
|
||||||
double wayfraction = -s2 / ( d * d );
|
double wayfraction = -s2 / ( d * d );
|
Loading…
Reference in a new issue