add rework vh process and add post process
This commit is contained in:
parent
c586245db5
commit
15dd1f30f1
2 changed files with 122 additions and 17 deletions
|
@ -1080,7 +1080,9 @@ public final class OsmTrack {
|
|||
VoiceHintProcessor vproc = new VoiceHintProcessor(rc.turnInstructionCatchingRange, rc.turnInstructionRoundabouts);
|
||||
List<VoiceHint> results = vproc.process(inputs);
|
||||
|
||||
for (VoiceHint hint : results) {
|
||||
double minDistance = getMinDistance();
|
||||
List < VoiceHint > resultsLast = vproc.postProcess(results, rc.turnInstructionCatchingRange, minDistance);
|
||||
for (VoiceHint hint: resultsLast) {
|
||||
voiceHints.list.add(hint);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,18 +9,22 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
public final class VoiceHintProcessor {
|
||||
private double catchingRange; // range to catch angles and merge turns
|
||||
|
||||
double SIGNIFICANT_ANGLE = 22.5;
|
||||
double INTERNAL_CATCHING_RANGE = 2.;
|
||||
|
||||
// private double catchingRange; // range to catch angles and merge turns
|
||||
private boolean explicitRoundabouts;
|
||||
|
||||
public VoiceHintProcessor(double catchingRange, boolean explicitRoundabouts) {
|
||||
this.catchingRange = catchingRange;
|
||||
// this.catchingRange = catchingRange;
|
||||
this.explicitRoundabouts = explicitRoundabouts;
|
||||
}
|
||||
|
||||
private float sumNonConsumedWithinCatchingRange(List<VoiceHint> inputs, int offset) {
|
||||
double distance = 0.;
|
||||
float angle = 0.f;
|
||||
while (offset >= 0 && distance < catchingRange) {
|
||||
while (offset >= 0 && distance < INTERNAL_CATCHING_RANGE) {
|
||||
VoiceHint input = inputs.get(offset--);
|
||||
if (input.turnAngleConsumed) {
|
||||
break;
|
||||
|
@ -60,6 +64,10 @@ public final class VoiceHintProcessor {
|
|||
for (int hintIdx = 0; hintIdx < inputs.size(); hintIdx++) {
|
||||
VoiceHint input = inputs.get(hintIdx);
|
||||
|
||||
if (input.cmd == VoiceHint.BL) {
|
||||
results.add(input);
|
||||
continue;
|
||||
}
|
||||
float turnAngle = input.goodWay.turnangle;
|
||||
distance += input.goodWay.linkdist;
|
||||
int currentPrio = input.goodWay.getPrio();
|
||||
|
@ -67,6 +75,7 @@ public final class VoiceHintProcessor {
|
|||
int minPrio = Math.min(oldPrio, currentPrio);
|
||||
|
||||
boolean isLink2Highway = input.oldWay.isLinktType() && !input.goodWay.isLinktType();
|
||||
boolean isHighway2Link = !input.oldWay.isLinktType() && input.goodWay.isLinktType();
|
||||
|
||||
if (input.oldWay.isRoundabout()) {
|
||||
roundAboutTurnAngle += sumNonConsumedWithinCatchingRange(inputs, hintIdx);
|
||||
|
@ -101,14 +110,18 @@ public final class VoiceHintProcessor {
|
|||
float minAngle = 180.f;
|
||||
float minAbsAngeRaw = 180.f;
|
||||
|
||||
boolean isBadwayLink = false;
|
||||
|
||||
if (input.badWays != null) {
|
||||
for (MessageData badWay : input.badWays) {
|
||||
int badPrio = badWay.getPrio();
|
||||
float badTurn = badWay.turnangle;
|
||||
if (badWay.isLinktType()) {
|
||||
isBadwayLink = true;
|
||||
}
|
||||
boolean isBadHighway2Link = !input.oldWay.isLinktType() && badWay.isLinktType();
|
||||
|
||||
boolean isHighway2Link = !input.oldWay.isLinktType() && badWay.isLinktType();
|
||||
|
||||
if (badPrio > maxPrioAll && !isHighway2Link) {
|
||||
if (badPrio > maxPrioAll && !isBadHighway2Link) {
|
||||
maxPrioAll = badPrio;
|
||||
}
|
||||
|
||||
|
@ -140,12 +153,17 @@ public final class VoiceHintProcessor {
|
|||
}
|
||||
}
|
||||
|
||||
boolean hasSomethingMoreStraight = Math.abs(turnAngle) - minAbsAngeRaw > 20.;
|
||||
boolean hasSomethingMoreStraight = (Math.abs(turnAngle) - minAbsAngeRaw) > 20.;
|
||||
|
||||
// unconditional triggers are all junctions with
|
||||
// - higher detour prios than the minimum route prio (except link->highway junctions)
|
||||
// - or candidate detours with higher prio then the route exit leg
|
||||
boolean unconditionalTrigger = hasSomethingMoreStraight || (maxPrioAll > minPrio && !isLink2Highway) || (maxPrioCandidates > currentPrio);
|
||||
boolean unconditionalTrigger = hasSomethingMoreStraight ||
|
||||
(maxPrioAll > minPrio && !isLink2Highway) ||
|
||||
(maxPrioCandidates > currentPrio) ||
|
||||
VoiceHint.is180DegAngle(turnAngle) ||
|
||||
(!isHighway2Link && isBadwayLink && Math.abs(turnAngle) > 5.f) ||
|
||||
(isHighway2Link && !isBadwayLink && Math.abs(turnAngle) < 5.f);
|
||||
|
||||
// conditional triggers (=real turning angle required) are junctions
|
||||
// with candidate detours equal in priority than the route exit leg
|
||||
|
@ -158,19 +176,21 @@ public final class VoiceHintProcessor {
|
|||
input.needsRealTurn = (!unconditionalTrigger) && isStraight;
|
||||
|
||||
// check for KR/KL
|
||||
if (maxAngle < turnAngle && maxAngle > turnAngle - 45.f - (turnAngle > 0.f ? turnAngle : 0.f)) {
|
||||
if (Math.abs(turnAngle) > 5.) { // don't use to small angles
|
||||
if (maxAngle < turnAngle && maxAngle > turnAngle - 45.f - (Math.max(turnAngle, 0.f))) {
|
||||
input.cmd = VoiceHint.KR;
|
||||
}
|
||||
if (minAngle > turnAngle && minAngle < turnAngle + 45.f - (turnAngle < 0.f ? turnAngle : 0.f)) {
|
||||
if (minAngle > turnAngle && minAngle < turnAngle + 45.f - (Math.min(turnAngle, 0.f))) {
|
||||
input.cmd = VoiceHint.KL;
|
||||
}
|
||||
}
|
||||
|
||||
input.angle = sumNonConsumedWithinCatchingRange(inputs, hintIdx);
|
||||
input.distanceToNext = distance;
|
||||
distance = 0.;
|
||||
results.add(input);
|
||||
}
|
||||
if (results.size() > 0 && distance < catchingRange) {
|
||||
if (results.size() > 0 && distance < INTERNAL_CATCHING_RANGE) { //catchingRange
|
||||
results.get(results.size() - 1).angle += sumNonConsumedWithinCatchingRange(inputs, hintIdx);
|
||||
}
|
||||
}
|
||||
|
@ -185,10 +205,10 @@ public final class VoiceHintProcessor {
|
|||
if (hint.cmd == 0) {
|
||||
hint.calcCommand();
|
||||
}
|
||||
if (!(hint.needsRealTurn && hint.cmd == VoiceHint.C)) {
|
||||
if (!(hint.needsRealTurn && (hint.cmd == VoiceHint.C || hint.cmd == VoiceHint.BL))) {
|
||||
double dist = hint.distanceToNext;
|
||||
// sum up other hints within the catching range (e.g. 40m)
|
||||
while (dist < catchingRange && i > 0) {
|
||||
while (dist < INTERNAL_CATCHING_RANGE && i > 0) {
|
||||
VoiceHint h2 = results.get(i - 1);
|
||||
dist = h2.distanceToNext;
|
||||
hint.distanceToNext += dist;
|
||||
|
@ -207,9 +227,92 @@ public final class VoiceHintProcessor {
|
|||
}
|
||||
hint.calcCommand();
|
||||
results2.add(hint);
|
||||
} else if (hint.cmd == VoiceHint.BL) {
|
||||
results2.add(hint);
|
||||
} else {
|
||||
if (results2.size() > 0)
|
||||
results2.get(results2.size() - 1).distanceToNext += hint.distanceToNext;
|
||||
}
|
||||
}
|
||||
return results2;
|
||||
}
|
||||
|
||||
public List<VoiceHint> postProcess(List<VoiceHint> inputs, double catchingRange, double minRange) {
|
||||
List<VoiceHint> results = new ArrayList<VoiceHint>();
|
||||
double distance = 0;
|
||||
VoiceHint inputLast = null;
|
||||
ArrayList<VoiceHint> tmpList = new ArrayList<>();
|
||||
for (int hintIdx = 0; hintIdx < inputs.size(); hintIdx++) {
|
||||
VoiceHint input = inputs.get(hintIdx);
|
||||
|
||||
if (input.cmd == VoiceHint.C && !input.goodWay.isLinktType()) {
|
||||
int badWayPrio = 0;
|
||||
for (MessageData md : input.badWays) {
|
||||
badWayPrio = Math.max(badWayPrio, md.getPrio());
|
||||
}
|
||||
if (input.goodWay.getPrio() < badWayPrio) {
|
||||
results.add(input);
|
||||
} else {
|
||||
if (inputLast != null) { // when drop add distance to last
|
||||
inputLast.distanceToNext += input.distanceToNext;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (input.distanceToNext < catchingRange) {
|
||||
double dist = input.distanceToNext;
|
||||
float angles = input.angle;
|
||||
int i = 1;
|
||||
boolean save = true;
|
||||
tmpList.clear();
|
||||
while (dist < catchingRange && hintIdx + i < inputs.size()) {
|
||||
VoiceHint h2 = inputs.get(hintIdx + i);
|
||||
dist += h2.distanceToNext;
|
||||
angles += h2.angle;
|
||||
if (VoiceHint.is180DegAngle(input.angle) || VoiceHint.is180DegAngle(h2.angle)) { // u-turn, 180 degree
|
||||
save = true;
|
||||
break;
|
||||
} else if (Math.abs(angles) > 180 - SIGNIFICANT_ANGLE) { // u-turn, collects e.g. two left turns in range
|
||||
input.angle = angles;
|
||||
input.calcCommand();
|
||||
input.distanceToNext += h2.distanceToNext;
|
||||
save = true;
|
||||
hintIdx++;
|
||||
break;
|
||||
} else if (Math.abs(angles) < SIGNIFICANT_ANGLE && input.distanceToNext < minRange) {
|
||||
input.angle = angles;
|
||||
input.calcCommand();
|
||||
input.distanceToNext += h2.distanceToNext;
|
||||
save = true;
|
||||
hintIdx++;
|
||||
break;
|
||||
} else if (Math.abs(input.angle) > SIGNIFICANT_ANGLE) {
|
||||
tmpList.add(h2);
|
||||
hintIdx++;
|
||||
} else if (dist > catchingRange) { // distance reached
|
||||
break;
|
||||
} else {
|
||||
if (inputLast != null) { // when drop add distance to last
|
||||
inputLast.distanceToNext += input.distanceToNext;
|
||||
}
|
||||
save = false;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (save) {
|
||||
results.add(input); // add when last
|
||||
if (tmpList.size() > 0) { // add when something in stock
|
||||
results.addAll(tmpList);
|
||||
hintIdx += tmpList.size() - 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
results.add(input);
|
||||
}
|
||||
inputLast = input;
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue