added speed profile to json result

This commit is contained in:
Arndt Brenschede 2019-01-26 19:50:04 +01:00
parent 7547d5d820
commit 137d87c085
8 changed files with 137 additions and 21 deletions

View file

@ -40,6 +40,7 @@ final class KinematicModel extends OsmPathModel
public double cost0; // minimum possible cost per meter
private int wayIdxMaxspeed;
private int wayIdxMaxspeedExplicit;
private int wayIdxMinspeed;
private int nodeIdxMaxspeed;
@ -61,6 +62,7 @@ final class KinematicModel extends OsmPathModel
ctxWay = expctxWay;
ctxNode = expctxNode;
wayIdxMaxspeed = ctxWay.getOutputVariableIndex( "maxspeed", false );
wayIdxMaxspeedExplicit = ctxWay.getOutputVariableIndex( "maxspeed_explicit", false );
wayIdxMinspeed = ctxWay.getOutputVariableIndex( "minspeed", false );
nodeIdxMaxspeed = ctxNode.getOutputVariableIndex( "maxspeed", false );
initDone = true;
@ -104,6 +106,11 @@ final class KinematicModel extends OsmPathModel
return ctxWay.getBuildInVariable( wayIdxMaxspeed ) / 3.6f;
}
public float getWayMaxspeedExplicit()
{
return ctxWay.getBuildInVariable( wayIdxMaxspeedExplicit ) / 3.6f;
}
public float getWayMinspeed()
{
return ctxWay.getBuildInVariable( wayIdxMinspeed ) / 3.6f;

View file

@ -76,6 +76,8 @@ final class KinematicPath extends OsmPath
if ( nsection == 0 ) // process slowdown by crossing geometry
{
double junctionspeed = 999.; // just high
int classifiermask = (int)rc.expctxWay.getClassifierMask();
// penalty for equal priority crossing
@ -105,16 +107,27 @@ final class KinematicPath extends OsmPath
}
double residentialSpeed = 13.;
if ( hasLeftWay && turnspeed > km.leftWaySpeed ) turnspeed = km.leftWaySpeed;
if ( hasRightWay && turnspeed > km.rightWaySpeed ) turnspeed = km.rightWaySpeed;
if ( hasResidential && turnspeed > residentialSpeed ) turnspeed = residentialSpeed;
if ( hasLeftWay && junctionspeed > km.leftWaySpeed ) junctionspeed = km.leftWaySpeed;
if ( hasRightWay && junctionspeed > km.rightWaySpeed ) junctionspeed = km.rightWaySpeed;
if ( hasResidential && junctionspeed > residentialSpeed ) junctionspeed = residentialSpeed;
if ( (lastpriorityclassifier < 20) ^ (priorityclassifier < 20) )
{
extraTime += 10.;
turnspeed = 0; // full stop for entering or leaving road network
junctionspeed = 0; // full stop for entering or leaving road network
}
if ( lastpriorityclassifier != priorityclassifier && (classifiermask & 8) != 0 )
{
extraTime += 2.; // two seconds for entering a link-type
}
turnspeed = turnspeed > junctionspeed ? junctionspeed : turnspeed;
if ( message != null )
{
message.vnode0 = (int) ( junctionspeed * 3.6 + 0.5 );
}
}
cutEkin( km.totalweight, turnspeed ); // apply turnspeed
}
@ -131,6 +144,10 @@ final class KinematicPath extends OsmPath
if ( message != null )
{
message.costfactor = (float)(distanceCost/dist);
message.vmax = (int) ( km.getWayMaxspeed() * 3.6 + 0.5 );
message.vmaxExplicit = (int) ( km.getWayMaxspeedExplicit() * 3.6 + 0.5 );
message.vmin = (int) ( km.getWayMinspeed() * 3.6 + 0.5 );
message.extraTime = (int)(extraTime*1000);
}
cost += extraTime * km.pw / km.cost0;
@ -242,6 +259,8 @@ final class KinematicPath extends OsmPath
{
message.linknodecost += (int)initialcost;
message.nodeKeyValues = rc.expctxNode.getKeyValueDescription( false, targetNode.nodeDescription );
message.vnode1 = (int) ( km.getNodeMaxspeed() * 3.6 + 0.5 );
}
return initialcost;
}

View file

@ -29,6 +29,14 @@ final class MessageData implements Cloneable
float time;
float energy;
// speed profile
int vmaxExplicit = -1;
int vmax = -1;
int vmin = -1;
int vnode0 = 999;
int vnode1 = 999;
int extraTime = 0;
String toMessage()
{
if ( wayKeyValues == null )

View file

@ -345,7 +345,7 @@ abstract class OsmPath implements OsmLinkHolder
{
if ( rc.startDirectionValid )
{
double dir = rc.startDirection.intValue() / CheapRulerSingleton.DEG_TO_RAD;
double dir = rc.startDirection.intValue() * CheapRulerSingleton.DEG_TO_RAD;
double[] lonlat2m = CheapRulerSingleton.getLonLatToMeterScales( (lon0 + lat1) >> 1 );
lon0 = lon1 - (int) ( 1000. * Math.sin( dir ) / lonlat2m[0] );
lat0 = lat1 - (int) ( 1000. * Math.cos( dir ) / lonlat2m[1] );

View file

@ -53,6 +53,8 @@ public final class OsmTrack
private VoiceHintList voiceHints;
private boolean sendSpeedProfile;
public String message = null;
public ArrayList<String> messageList = null;
@ -146,6 +148,31 @@ public final class OsmTrack
return res;
}
private ArrayList<String> aggregateSpeedProfile()
{
ArrayList<String> res = new ArrayList<String>();
int vmax = -1;
int vmaxe = -1;
int vmin = -1;
int extraTime = 0;
for( int i = nodes.size()-1; i > 0; i-- )
{
OsmPathElement n = nodes.get(i);
MessageData m = n.message;
int vnode = getVNode( i );
if ( m != null && ( vmax != m.vmax || vmin != m.vmin || vmaxe != m.vmaxExplicit || vnode < m.vmax || extraTime != m.extraTime ) )
{
vmax = m.vmax;
vmin = m.vmin;
vmaxe = m.vmaxExplicit;
extraTime = m.extraTime;
res.add( i + "," + vmaxe + "," + vmax + "," + vmin + "," + vnode + "," + extraTime );
}
}
return res;
}
/**
* writes the track in binary-format to a file
*
@ -324,6 +351,7 @@ public final class OsmTrack
energy += t.energy;
showspeed |= t.showspeed;
sendSpeedProfile |= t.sendSpeedProfile;
}
public int distance;
@ -563,24 +591,41 @@ public final class OsmTrack
sb.append( " \"total-time\": \"" ).append( getTotalSeconds() ).append( "\",\n" );
sb.append( " \"total-energy\": \"" ).append( energy ).append( "\",\n" );
sb.append( " \"cost\": \"" ).append( cost ).append( "\",\n" );
sb.append( " \"voicehints\": [\n" );
for( VoiceHint hint: voiceHints.list )
if ( voiceHints != null && !voiceHints.list.isEmpty() )
{
sb.append( " [" ).append( hint.indexInTrack ).append( ',' ).append( hint.getCommand() ).append( ',' ).append( hint.getExitNumber() ).append( "],\n" );
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.deleteCharAt( sb.lastIndexOf( "," ) );
sb.append( " ],\n" );
}
sb.deleteCharAt( sb.lastIndexOf( "," ) );
sb.append( " ],\n" );
sb.append( " \"messages\": [\n" );
sb.append( " [\"" ).append( MESSAGES_HEADER.replaceAll( "\t", "\", \"" ) ).append( "\"],\n" );
for ( String m : aggregateMessages() )
if ( sendSpeedProfile ) // true if vmax was send
{
sb.append( " [\"" ).append( m.replaceAll( "\t", "\", \"" ) ).append( "\"],\n" );
ArrayList<String> sp = aggregateSpeedProfile();
if ( sp.size() > 0 )
{
sb.append( " \"speedprofile\": [\n" );
for( int i=sp.size()-1; i>=0; i-- )
{
sb.append( " [" ).append( sp.get(i) ).append( i> 0 ? "],\n" : "]\n" );
}
sb.append( " ]\n" );
}
}
else // ... otherwise traditional message list
{
sb.append( " \"messages\": [\n" );
sb.append( " [\"" ).append( MESSAGES_HEADER.replaceAll( "\t", "\", \"" ) ).append( "\"],\n" );
for ( String m : aggregateMessages() )
{
sb.append( " [\"" ).append( m.replaceAll( "\t", "\", \"" ) ).append( "\"],\n" );
}
sb.deleteCharAt( sb.lastIndexOf( "," ) );
sb.append( " ]\n" );
}
sb.deleteCharAt( sb.lastIndexOf( "," ) );
sb.append( " ]\n" );
sb.append( " },\n" );
if ( iternity != null )
{
sb.append( " \"iternity\": [\n" );
@ -628,6 +673,15 @@ public final class OsmTrack
return sb.toString();
}
private int getVNode( int i )
{
MessageData m1 = i+1 < nodes.size() ? nodes.get(i+1).message : null;
MessageData m0 = i < nodes.size() ? nodes.get(i ).message : null;
int vnode0 = m1 == null ? 999 : m1.vnode0;
int vnode1 = m0 == null ? 999 : m0.vnode1;
return vnode0 < vnode1 ? vnode0 : vnode1;
}
private int getTotalSeconds()
{
float s = nodes.size() < 2 ? 0 : nodes.get( nodes.size()-1 ).getTime() - nodes.get( 0 ).getTime();
@ -755,6 +809,11 @@ public final class OsmTrack
return true;
}
public void prepareSpeedProfile( RoutingContext rc )
{
sendSpeedProfile = rc.keyValues != null && rc.keyValues.containsKey( "vmax" );
}
public void processVoiceHints( RoutingContext rc )
{
voiceHints = new VoiceHintList();

View file

@ -192,6 +192,7 @@ public final class RoutingContext
public Integer startDirection;
public boolean startDirectionValid;
public boolean forceUseStartDirection;
private double cosangle;
public double nogoCost = 0.;

View file

@ -808,7 +808,9 @@ public class RoutingEngine extends Thread
if ( start1 == null || start2 == null ) return null;
if ( routingContext.startDirectionValid = ( fastPartialRecalc && routingContext.startDirection != null && !routingContext.inverseDirection ) )
routingContext.startDirectionValid = routingContext.forceUseStartDirection || fastPartialRecalc;
routingContext.startDirectionValid &= routingContext.startDirection != null && !routingContext.inverseDirection;
if ( routingContext.startDirectionValid )
{
logInfo( "using start direction " + routingContext.startDirection );
}
@ -1221,6 +1223,7 @@ public class RoutingEngine extends Thread
{
track.copyDetours( guideTrack );
track.processVoiceHints( routingContext );
track.prepareSpeedProfile( routingContext );
}
return track;
}

View file

@ -188,7 +188,26 @@ public class RouteServer extends Thread
{
NearRecentWps.add( wplist );
}
for( Map.Entry<String,String> e : params.entrySet() )
{
if ( "timode".equals( e.getKey() ) )
{
rc.turnInstructionMode = Integer.parseInt( e.getValue() );
}
else if ( "heading".equals( e.getKey() ) )
{
rc.startDirection = Integer.valueOf( Integer.parseInt( e.getValue() ) );
rc.forceUseStartDirection = true;
}
else if ( e.getKey().startsWith( "profile:" ) )
{
if ( rc.keyValues == null )
{
rc.keyValues = new HashMap<String,String>();
}
rc.keyValues.put( e.getKey().substring( 8 ), e.getValue() );
}
}
cr = new RoutingEngine( null, null, serviceContext.segmentDir, wplist, rc );
cr.quite = true;
cr.doRun( maxRunningTime );