bee-line patch: Nogo covering 2 Waypoints triggers a beeline segment

This commit is contained in:
Arndt Brenschede 2021-03-31 16:07:21 +02:00
parent 372a04a6cf
commit eb716506fd
3 changed files with 77 additions and 7 deletions

View file

@ -139,7 +139,10 @@ abstract class OsmPath implements OsmLinkHolder
protected void addAddionalPenalty(OsmTrack refTrack, boolean detailMode, OsmPath origin, OsmLink link, RoutingContext rc ) protected void addAddionalPenalty(OsmTrack refTrack, boolean detailMode, OsmPath origin, OsmLink link, RoutingContext rc )
{ {
byte[] description = link.descriptionBitmap; byte[] description = link.descriptionBitmap;
if ( description == null ) throw new IllegalArgumentException( "null description for: " + link ); if ( description == null )
{
return; // could be a beeline path
}
boolean recordTransferNodes = detailMode || rc.countTraffic; boolean recordTransferNodes = detailMode || rc.countTraffic;

View file

@ -16,6 +16,7 @@ import btools.expressions.BExpressionContextNode;
import btools.expressions.BExpressionContextWay; import btools.expressions.BExpressionContextWay;
import btools.mapaccess.GeometryDecoder; import btools.mapaccess.GeometryDecoder;
import btools.mapaccess.OsmLink; import btools.mapaccess.OsmLink;
import btools.mapaccess.OsmNode;
import btools.util.CheapAngleMeter; import btools.util.CheapAngleMeter;
import btools.util.CheapRuler; import btools.util.CheapRuler;
@ -191,6 +192,7 @@ public final class RoutingContext
public List<OsmNodeNamed> poipoints; public List<OsmNodeNamed> poipoints;
public List<OsmNodeNamed> nogopoints = null; public List<OsmNodeNamed> nogopoints = null;
private List<OsmNodeNamed> nogopoints_all = null; // full list not filtered for wayoints-in-nogos
private List<OsmNodeNamed> keepnogopoints = null; private List<OsmNodeNamed> keepnogopoints = null;
private OsmNodeNamed pendingEndpoint = null; private OsmNodeNamed pendingEndpoint = null;
@ -258,14 +260,29 @@ public final class RoutingContext
} }
} }
public void cleanNogolist( List<OsmNodeNamed> waypoints ) /**
* restore the full nogolist previously saved by cleanNogoList
*/
public void restoreNogoList()
{ {
nogopoints = nogopoints_all;
}
/**
* clean the nogolist (previoulsy saved by saveFullNogolist())
* by removing nogos with waypoints within
*
* @return true if all wayoints are all in the same (full-weigth) nogo area (triggering bee-line-mode)
*/
public void cleanNogoList( List<OsmNode> waypoints )
{
nogopoints_all = nogopoints;
if ( nogopoints == null ) return; if ( nogopoints == null ) return;
List<OsmNodeNamed> nogos = new ArrayList<OsmNodeNamed>(); List<OsmNodeNamed> nogos = new ArrayList<OsmNodeNamed>();
for( OsmNodeNamed nogo : nogopoints ) for( OsmNodeNamed nogo : nogopoints )
{ {
boolean goodGuy = true; boolean goodGuy = true;
for( OsmNodeNamed wp : waypoints ) for( OsmNode wp : waypoints )
{ {
if ( wp.calcDistance( nogo ) < nogo.radius if ( wp.calcDistance( nogo ) < nogo.radius
&& (!(nogo instanceof OsmNogoPolygon) && (!(nogo instanceof OsmNogoPolygon)
@ -274,7 +291,6 @@ public final class RoutingContext
: ((OsmNogoPolygon)nogo).isOnPolyline(wp.ilon, wp.ilat)))) : ((OsmNogoPolygon)nogo).isOnPolyline(wp.ilon, wp.ilat))))
{ {
goodGuy = false; goodGuy = false;
break;
} }
} }
if ( goodGuy ) nogos.add( nogo ); if ( goodGuy ) nogos.add( nogo );
@ -282,6 +298,31 @@ public final class RoutingContext
nogopoints = nogos.isEmpty() ? null : nogos; nogopoints = nogos.isEmpty() ? null : nogos;
} }
public boolean allInOneNogo( List<OsmNode> waypoints )
{
if ( nogopoints == null ) return false;
boolean allInTotal = false;
for( OsmNodeNamed nogo : nogopoints )
{
boolean allIn = Double.isNaN( nogo.nogoWeight );
for( OsmNode wp : waypoints )
{
int dist = wp.calcDistance( nogo );
if ( dist < nogo.radius
&& (!(nogo instanceof OsmNogoPolygon)
|| (((OsmNogoPolygon)nogo).isClosed
? ((OsmNogoPolygon)nogo).isWithin(wp.ilon, wp.ilat)
: ((OsmNogoPolygon)nogo).isOnPolyline(wp.ilon, wp.ilat))))
{
continue;
}
allIn = false;
}
allInTotal |= allIn;
}
return allInTotal;
}
public long[] getNogoChecksums() public long[] getNogoChecksums()
{ {
long[] cs = new long[3]; long[] cs = new long[3];

View file

@ -151,9 +151,6 @@ public class RoutingEngine extends Thread
{ {
try try
{ {
// delete nogos with waypoints in them
routingContext.cleanNogolist( waypoints );
startTime = System.currentTimeMillis(); startTime = System.currentTimeMillis();
long startTime0 = startTime; long startTime0 = startTime;
this.maxRunningTime = maxRunningTime; this.maxRunningTime = maxRunningTime;
@ -459,6 +456,29 @@ public class RoutingEngine extends Thread
} }
private OsmTrack searchTrack( MatchedWaypoint startWp, MatchedWaypoint endWp, OsmTrack nearbyTrack, OsmTrack refTrack ) private OsmTrack searchTrack( MatchedWaypoint startWp, MatchedWaypoint endWp, OsmTrack nearbyTrack, OsmTrack refTrack )
{
// remove nogos with waypoints inside
try
{
List<OsmNode> wpts2 = new ArrayList<OsmNode>();
wpts2.add( startWp.waypoint );
wpts2.add( endWp.waypoint );
boolean calcBeeline = routingContext.allInOneNogo(wpts2);
if ( !calcBeeline ) return searchRoutedTrack( startWp, endWp, nearbyTrack, refTrack );
// we want a beeline-segment
OsmPath path = routingContext.createPath( new OsmLink( null, startWp.crosspoint ) );
path = routingContext.createPath( path, new OsmLink( startWp.crosspoint, endWp.crosspoint ), null, false );
return compileTrack( path, false );
}
finally
{
routingContext.restoreNogoList();
}
}
private OsmTrack searchRoutedTrack( MatchedWaypoint startWp, MatchedWaypoint endWp, OsmTrack nearbyTrack, OsmTrack refTrack )
{ {
OsmTrack track = null; OsmTrack track = null;
double[] airDistanceCostFactors = new double[]{ routingContext.pass1coefficient, routingContext.pass2coefficient }; double[] airDistanceCostFactors = new double[]{ routingContext.pass1coefficient, routingContext.pass2coefficient };
@ -650,6 +670,11 @@ public class RoutingEngine extends Thread
{ {
try try
{ {
List<OsmNode> wpts2 = new ArrayList<OsmNode>();
if ( startWp != null ) wpts2.add( startWp.waypoint );
if ( endWp != null ) wpts2.add( endWp.waypoint );
routingContext.cleanNogoList(wpts2);
boolean detailed = guideTrack != null; boolean detailed = guideTrack != null;
resetCache( detailed ); resetCache( detailed );
nodesCache.nodesMap.cleanupMode = detailed ? 0 : ( routingContext.considerTurnRestrictions ? 2 : 1 ); nodesCache.nodesMap.cleanupMode = detailed ? 0 : ( routingContext.considerTurnRestrictions ? 2 : 1 );
@ -657,6 +682,7 @@ public class RoutingEngine extends Thread
} }
finally finally
{ {
routingContext.restoreNogoList();
nodesCache.clean( false ); // clean only non-virgin caches nodesCache.clean( false ); // clean only non-virgin caches
} }
} }