rework same-segment search logic

This commit is contained in:
Arndt Brenschede 2020-06-28 13:52:45 +02:00
parent 7e4bcebd3c
commit cdd3a80b9e
3 changed files with 51 additions and 71 deletions

View file

@ -298,6 +298,16 @@ abstract class OsmPath implements OsmLinkHolder
originElement = null; // prevent duplicate point originElement = null; // prevent duplicate point
} }
} }
if ( rc.checkPendingEndpoint() )
{
dist = rc.calcDistance( rc.ilonshortest, rc.ilatshortest, lon2, lat2 );
if ( rc.shortestmatch )
{
stopAtEndpoint = true;
ele2 = interpolateEle( ele1, ele2, rc.wayfraction );
}
}
} }
} }

View file

@ -192,6 +192,7 @@ public final class RoutingContext
public List<OsmNodeNamed> nogopoints = null; public List<OsmNodeNamed> nogopoints = null;
private List<OsmNodeNamed> keepnogopoints = null; private List<OsmNodeNamed> keepnogopoints = null;
private OsmNodeNamed pendingEndpoint = null;
public Integer startDirection; public Integer startDirection;
public boolean startDirectionValid; public boolean startDirectionValid;
@ -297,17 +298,36 @@ public final class RoutingContext
} }
public void setWaypoint( OsmNodeNamed wp, boolean endpoint ) public void setWaypoint( OsmNodeNamed wp, boolean endpoint )
{
setWaypoint( wp, null, endpoint );
}
public void setWaypoint( OsmNodeNamed wp, OsmNodeNamed pendingEndpoint, boolean endpoint )
{ {
keepnogopoints = nogopoints; keepnogopoints = nogopoints;
nogopoints = new ArrayList<OsmNodeNamed>(); nogopoints = new ArrayList<OsmNodeNamed>();
nogopoints.add( wp ); nogopoints.add( wp );
if ( keepnogopoints != null ) nogopoints.addAll( keepnogopoints ); if ( keepnogopoints != null ) nogopoints.addAll( keepnogopoints );
isEndpoint = endpoint; isEndpoint = endpoint;
this.pendingEndpoint = pendingEndpoint;
}
public boolean checkPendingEndpoint()
{
if ( pendingEndpoint != null )
{
isEndpoint = true;
nogopoints.set( 0, pendingEndpoint );
pendingEndpoint = null;
return true;
}
return false;
} }
public void unsetWaypoint() public void unsetWaypoint()
{ {
nogopoints = keepnogopoints; nogopoints = keepnogopoints;
pendingEndpoint = null;
isEndpoint = false; isEndpoint = false;
} }

View file

@ -587,62 +587,27 @@ public class RoutingEngine extends Thread
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, new OsmNodeNamed( mwp.waypoint ), endPos ); if ( endPos != null )
{
endPos.radius = 1.5;
}
OsmPath p = getStartPath( n1, n2, new OsmNodeNamed( mwp.crosspoint ), endPos, sameSegmentSearch );
// special case: start+end on same segment // special case: start+end on same segment
if ( p.cost >= 0 && sameSegmentSearch ) if ( p.cost >= 0 && sameSegmentSearch && endPos != null && endPos.radius < 1.5 )
{ {
OsmPath path2end = getStartPath( n1, n2, endPos, endPos ); p.treedepth = 0; // hack: mark for the final-check
boolean isDirect = path2end.cost >= p.cost;
OsmPath pe = getEndPath( n1, p.getLink(), endPos );
OsmPath pt = getEndPath( n1, p.getLink(), null );
int costdelta = pt.cost - p.cost;
if ( isDirect && pe.cost < costdelta )
{
costdelta = pe.cost;
}
if ( pe.cost >= costdelta )
{
pe.cost -= costdelta;
if ( guideTrack != null )
{
// nasty stuff: combine the path cause "new OsmPath()" cannot handle start+endpoint
OsmPathElement startElement = p.originElement;
while( startElement.origin != null )
{
startElement = startElement.origin;
}
if ( pe.originElement.cost > costdelta )
{
OsmPathElement e = pe.originElement;
while( e.origin != null && e.origin.cost > costdelta )
{
e = e.origin;
e.cost -= costdelta;
}
e.origin = startElement;
}
else
{
pe.originElement = startElement;
}
}
pe.treedepth = 0; // hack: mark for the final-check
return pe;
}
} }
return p; return p;
} }
private OsmPath getStartPath( OsmNode n1, OsmNode n2, OsmNodeNamed wp, OsmNodeNamed endPos ) private OsmPath getStartPath( OsmNode n1, OsmNode n2, OsmNodeNamed wp, OsmNodeNamed endPos, boolean sameSegmentSearch )
{ {
try try
{ {
routingContext.setWaypoint( wp, false ); routingContext.setWaypoint( wp, sameSegmentSearch ? endPos : null, false );
OsmPath bestPath = null; OsmPath bestPath = null;
OsmLink bestLink = null; OsmLink bestLink = null;
OsmLink startLink = new OsmLink( null, n1 ); OsmLink startLink = new OsmLink( null, n1 );
@ -657,7 +622,7 @@ public class RoutingEngine extends Thread
if ( nextNode == n1 ) continue; // ? if ( nextNode == n1 ) continue; // ?
if ( nextNode != n2 ) continue; // just that link if ( nextNode != n2 ) continue; // just that link
wp.radius = 1e9; wp.radius = 1.5;
OsmPath testPath = routingContext.createPath( startPath, link, null, guideTrack != null ); OsmPath testPath = routingContext.createPath( startPath, link, null, guideTrack != null );
testPath.airdistance = endPos == null ? 0 : nextNode.calcDistance( endPos ); testPath.airdistance = endPos == null ? 0 : nextNode.calcDistance( endPos );
if ( wp.radius < minradius ) if ( wp.radius < minradius )
@ -681,25 +646,6 @@ public class RoutingEngine extends Thread
} }
} }
private OsmPath getEndPath( OsmNode n1, OsmLink link, OsmNodeNamed wp )
{
try
{
if ( wp != null ) routingContext.setWaypoint( wp, true );
OsmLink startLink = new OsmLink( null, n1 );
OsmPath startPath = routingContext.createPath( startLink );
startLink.addLinkHolder( startPath, null );
if ( wp != null ) wp.radius = 1.5;
return routingContext.createPath( startPath, link, null, guideTrack != null );
}
finally
{
if ( wp != null ) routingContext.unsetWaypoint();
}
}
private OsmTrack findTrack( String operationName, MatchedWaypoint startWp, MatchedWaypoint endWp, OsmTrack costCuttingTrack, OsmTrack refTrack, boolean fastPartialRecalc ) private OsmTrack findTrack( String operationName, MatchedWaypoint startWp, MatchedWaypoint endWp, OsmTrack costCuttingTrack, OsmTrack refTrack, boolean fastPartialRecalc )
{ {
try try
@ -985,13 +931,16 @@ public class RoutingEngine extends Thread
((OsmPath)linkHolder).airdistance = -1; // invalidate the entry in the open set; ((OsmPath)linkHolder).airdistance = -1; // invalidate the entry in the open set;
} }
if ( path.treedepth > 1 )
{
boolean isBidir = currentLink.isBidirectional(); boolean isBidir = currentLink.isBidirectional();
sourceNode.unlinkLink ( currentLink ); sourceNode.unlinkLink( currentLink );
// if the counterlink is alive and does not yet have a path, remove it // if the counterlink is alive and does not yet have a path, remove it
if ( isBidir && currentLink.getFirstLinkHolder( currentNode ) == null && !routingContext.considerTurnRestrictions ) if ( isBidir && currentLink.getFirstLinkHolder( currentNode ) == null && !routingContext.considerTurnRestrictions )
{ {
currentNode.unlinkLink(currentLink); currentNode.unlinkLink( currentLink );
}
} }
// recheck cutoff before doing expensive stuff // recheck cutoff before doing expensive stuff
@ -1123,7 +1072,8 @@ public class RoutingEngine extends Thread
OsmLinkHolder dominator = link.getFirstLinkHolder( currentNode ); OsmLinkHolder dominator = link.getFirstLinkHolder( currentNode );
while( !trafficSim && dominator != null ) while( !trafficSim && dominator != null )
{ {
if ( bestPath.definitlyWorseThan( (OsmPath)dominator, routingContext ) ) OsmPath dp = (OsmPath)dominator;
if ( dp.airdistance != -1 && bestPath.definitlyWorseThan( dp, routingContext ) )
{ {
break; break;
} }