Merge branch 'abrensch:master' into master

This commit is contained in:
afischerdev 2021-06-24 12:34:38 +02:00 committed by GitHub
commit f59eb0de1e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 440 additions and 89 deletions

View file

@ -55,7 +55,9 @@ final class MessageData implements Cloneable
+ "\t" + linknodecost
+ "\t" + linkinitcost
+ "\t" + wayKeyValues
+ "\t" + ( nodeKeyValues == null ? "" : nodeKeyValues );
+ "\t" + ( nodeKeyValues == null ? "" : nodeKeyValues )
+ "\t" + ((int)time)
+ "\t" + ((int)energy);
}
void add( MessageData d )

View file

@ -139,7 +139,10 @@ abstract class OsmPath implements OsmLinkHolder
protected void addAddionalPenalty(OsmTrack refTrack, boolean detailMode, OsmPath origin, OsmLink link, RoutingContext rc )
{
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;

View file

@ -19,8 +19,11 @@ import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import btools.mapaccess.MatchedWaypoint;
import btools.mapaccess.OsmPos;
@ -31,7 +34,7 @@ import btools.util.StringUtils;
public final class OsmTrack
{
// csv-header-line
private static final String MESSAGES_HEADER = "Longitude\tLatitude\tElevation\tDistance\tCostPerKm\tElevCost\tTurnCost\tNodeCost\tInitialCost\tWayTags\tNodeTags";
private static final String MESSAGES_HEADER = "Longitude\tLatitude\tElevation\tDistance\tCostPerKm\tElevCost\tTurnCost\tNodeCost\tInitialCost\tWayTags\tNodeTags\tTime\tEnergy";
public MatchedWaypoint endPoint;
public long[] nogoChecksums;
@ -719,6 +722,8 @@ public final class OsmTrack
public String formatAsGeoJson()
{
int turnInstructionMode = voiceHints != null ? voiceHints.turnInstructionMode : 0;
StringBuilder sb = new StringBuilder( 8192 );
sb.append( "{\n" );
@ -740,7 +745,20 @@ public final class OsmTrack
sb.append( " \"voicehints\": [\n" );
for( VoiceHint hint: voiceHints.list )
{
sb.append( " [" ).append( hint.indexInTrack ).append( ',' ).append( hint.getCommand() ).append( ',' ).append( hint.getExitNumber() ).append( "],\n" );
sb.append( " [" );
sb.append( hint.indexInTrack );
sb.append( ',' ).append( hint.getCommand() );
sb.append( ',' ).append( hint.getExitNumber() );
sb.append( ',' ).append( hint.distanceToNext );
sb.append( ',' ).append( (int) hint.angle );
// not always include geometry because longer and only needed for comment style
if ( turnInstructionMode == 4 ) // comment style
{
sb.append( ",\"" ).append( hint.formatGeometry() ).append( "\"" );
}
sb.append( "],\n" );
}
sb.deleteCharAt( sb.lastIndexOf( "," ) );
sb.append( " ],\n" );
@ -755,7 +773,7 @@ public final class OsmTrack
{
sb.append( " [" ).append( sp.get(i) ).append( i> 0 ? "],\n" : "]\n" );
}
sb.append( " ]\n" );
sb.append( " ],\n" );
}
}
else // ... otherwise traditional message list
@ -767,9 +785,24 @@ public final class OsmTrack
sb.append( " [\"" ).append( m.replaceAll( "\t", "\", \"" ) ).append( "\"],\n" );
}
sb.deleteCharAt( sb.lastIndexOf( "," ) );
sb.append( " ]\n" );
sb.append( " ],\n" );
}
if ( getTotalSeconds() > 0 ) {
sb.append( " \"times\": [" );
DecimalFormat decimalFormat = (DecimalFormat) NumberFormat.getInstance( Locale.ENGLISH );
decimalFormat.applyPattern( "0.###" );
for ( OsmPathElement n : nodes ) {
sb.append( decimalFormat.format( n.getTime() ) ).append( "," );
}
sb.deleteCharAt( sb.lastIndexOf( "," ) );
sb.append( "]\n" );
} else {
sb.deleteCharAt( sb.lastIndexOf( "," ) );
}
sb.append( " },\n" );
if ( iternity != null )
{
sb.append( " \"iternity\": [\n" );

View file

@ -16,6 +16,7 @@ import btools.expressions.BExpressionContextNode;
import btools.expressions.BExpressionContextWay;
import btools.mapaccess.GeometryDecoder;
import btools.mapaccess.OsmLink;
import btools.mapaccess.OsmNode;
import btools.util.CheapAngleMeter;
import btools.util.CheapRuler;
@ -191,6 +192,7 @@ public final class RoutingContext
public List<OsmNodeNamed> poipoints;
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 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;
List<OsmNodeNamed> nogos = new ArrayList<OsmNodeNamed>();
for( OsmNodeNamed nogo : nogopoints )
{
boolean goodGuy = true;
for( OsmNodeNamed wp : waypoints )
for( OsmNode wp : waypoints )
{
if ( wp.calcDistance( nogo ) < nogo.radius
&& (!(nogo instanceof OsmNogoPolygon)
@ -274,7 +291,6 @@ public final class RoutingContext
: ((OsmNogoPolygon)nogo).isOnPolyline(wp.ilon, wp.ilat))))
{
goodGuy = false;
break;
}
}
if ( goodGuy ) nogos.add( nogo );
@ -282,6 +298,31 @@ public final class RoutingContext
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()
{
long[] cs = new long[3];

View file

@ -151,9 +151,6 @@ public class RoutingEngine extends Thread
{
try
{
// delete nogos with waypoints in them
routingContext.cleanNogolist( waypoints );
startTime = System.currentTimeMillis();
long startTime0 = startTime;
this.maxRunningTime = maxRunningTime;
@ -459,6 +456,29 @@ public class RoutingEngine extends Thread
}
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;
double[] airDistanceCostFactors = new double[]{ routingContext.pass1coefficient, routingContext.pass2coefficient };
@ -650,6 +670,11 @@ public class RoutingEngine extends Thread
{
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;
resetCache( detailed );
nodesCache.nodesMap.cleanupMode = detailed ? 0 : ( routingContext.considerTurnRestrictions ? 2 : 1 );
@ -657,6 +682,7 @@ public class RoutingEngine extends Thread
}
finally
{
routingContext.restoreNogoList();
nodesCache.clean( false ); // clean only non-virgin caches
}
}