Really sorry, previous patch was wrong. Correct one attached Ticker
Index: src/uk/me/parabola/imgfmt/app/net/AngleChecker.java =================================================================== --- src/uk/me/parabola/imgfmt/app/net/AngleChecker.java (revision 4921) +++ src/uk/me/parabola/imgfmt/app/net/AngleChecker.java (working copy) @@ -68,8 +68,9 @@ // If this is >= above, then compactDirs will be used unless other, non-vehicle access angles are sharp private static final float SHARP_DEGREES = COMPACT_DIR_DEGREES; // Experimentation found no benefit in increasing angle beyond 2 "sectors" - private static final float MIN_ANGLE = 11.25f; // don't reduce angles to less than this (arbitrary) - + private static final float MIN_ANGLE = 23f; // don't reduce angles to less than this (1 sector + bit) + private static final float STRAIGHT_EPSILON = 3f; // for angle.straightAnough() + // helper class to collect multiple arcs with (nearly) the same initial headings private class ArcGroup { float initialHeading; @@ -106,7 +107,27 @@ public boolean isForward() { return isForwardTrueCount == arcs.size(); } - + + public boolean sameWay(ArcGroup other) { + for (RoadDef thisRoad : roadDefs) + for (RoadDef otherRoad : other.roadDefs) { + if (thisRoad.getId() == otherRoad.getId()) + return true; + } + return false; + } + + public boolean sameName(ArcGroup other) { + for (RoadDef thisRoad : roadDefs) + for (RoadDef otherRoad : other.roadDefs) { + String thisName = thisRoad.getName(); + if (thisName != null) + if (thisName.equals(otherRoad.getName())) + return true; + } + return false; + } + public void modInitialHeading(float modIH) { initialHeading += modIH; if (initialHeading >= 180) @@ -116,6 +137,7 @@ for (RouteArc arc : arcs) { arc.modInitialHeading(modIH); + log.info("modInitHead", arc, modIH, initialHeading); } } @@ -152,12 +174,20 @@ // Combine arcs with nearly the same initial heading. + if (log.isInfoEnabled()) + log.info("fixSharpAngles", node, sharpAnglesCheckMask, arcs.size()); + // first get direct arcs leaving the node List<RouteArc> directArcs = new ArrayList<>(); for (RouteArc arc : arcs) { - if (arc.isDirect()) + if (arc.isDirect()) { + if (log.isInfoEnabled()) { + RoadDef rd = arc.getRoadDef(); + log.info("directArc", /*arc,*/ arc.getInitialHeading(), rd.getId(), rd.getName(), + rd.getRoadSpeed(), rd.getRoadClass(), rd.paved()); + } directArcs.add(arc); - else + } else // AngleChecker runs before addArcsToMajorRoads so there shouldn't be any indirect arcs yet. // If this changes, extra care needs to be taken check they are positioned correctly in the list // of arcs or that their heading is kept consistent with changes to their direct base arc. @@ -237,6 +267,11 @@ class AngleAttr { float angle; float minAngle; + + private boolean straightAnough() { + return angle > 180-STRAIGHT_EPSILON && angle < 180+STRAIGHT_EPSILON; + } + } AngleAttr[] angles = new AngleAttr[n]; @@ -249,6 +284,8 @@ if (i+1 >= n) aa.angle += 360; aa.minAngle = Math.min(MIN_ANGLE, aa.angle); + log.info("AngleCalc", node, ag1.getInitialHeading(), aa.angle, ag2.getInitialHeading(), aa.minAngle); + float saveMinAngle = aa.minAngle; if (ag1.isOneway() && ag2.isOneway() && (ag1.isForward() == ag2.isForward())) @@ -317,8 +354,10 @@ if (wantedIncrement <= 0) continue; float oldAngle = aa.angle; + ArcGroup ag0 = null; ArcGroup ag1 = arcGroups.get(i); ArcGroup ag2 = arcGroups.get(i+1 < n ? i+1 : 0); + ArcGroup ag3 = null; if (log.isInfoEnabled()){ log.info("sharp angle", aa.angle, "° at", node.getCoord(), "headings", getCompassBearing(ag1.getInitialHeading()), getCompassBearing(ag2.getInitialHeading()), @@ -336,13 +375,47 @@ float deltaNext = nextAA.angle - nextAA.minAngle; if (deltaNext > 0 && deltaPred > 0) { // can take from both - if (ag1.maxRoadClass == ag2.maxRoadClass && - ag1.maxRoadSpeed == ag2.maxRoadSpeed) { // take from both in ratio to available + int chooseWhich = 0; // -ve to prefer to take from prev, +ve take from next + // order of {road_class, sameWay, straightness, roadName, road_speed} adjusted for priority + // Hoping sameWay before road_class fixing more problems than it might cause + if (chooseWhich == 0) { + // if the two arcs either side of the sharp angle belong to the same + // way then change the arc on the other side hoping to trigger + // the correct turn-instruction + ag0 = arcGroups.get(i > 0 ? i-1 : n-1); + ag3 = n == 3 ? ag0 : arcGroups.get(i+2 < n ? i+2 : i+2-n); + if (ag2.sameWay(ag3)) + chooseWhich = -1; + else if (ag1.sameWay(ag0)) + chooseWhich = +1; + } + if (chooseWhich == 0) + chooseWhich = ag1.maxRoadClass - ag2.maxRoadClass; + if (chooseWhich == 0) { + // where there is a straight road with a sharp turn-off then just adjust + // the turn-off. This is treated as a special case because the general + // logic below will adjust the adjust the straight road slightly more + // than the turn-off and, in some cases, with compactDirs, turn-instructions + if (nextAA.straightAnough()) + chooseWhich = -1; + else if (predAA.straightAnough()) + chooseWhich = +1; + } + if (chooseWhich == 0) { + // NB set ag0 & 3 if move this before sameWay() + // Way might have changed but could still be the same road by name or ref + if (ag2.sameName(ag3)) + chooseWhich = -1; + else if (ag1.sameName(ag0)) + chooseWhich = +1; + } + if (chooseWhich == 0) + chooseWhich = ag1.maxRoadSpeed - ag2.maxRoadSpeed; + + if (chooseWhich == 0 ) { // take from both in ratio to available deltaNext = Math.min(deltaNext, wantedIncrement * deltaNext / (deltaNext + deltaPred)); deltaPred = Math.min(deltaPred, wantedIncrement - deltaNext); - } else if (ag1.maxRoadClass > ag2.maxRoadClass || - (ag1.maxRoadClass == ag2.maxRoadClass && - ag1.maxRoadSpeed > ag2.maxRoadSpeed)) { // take as much as poss from next + } else if (chooseWhich > 0) { // take as much as poss from next if (deltaNext >= wantedIncrement) { deltaNext = wantedIncrement; deltaPred = 0; @@ -349,7 +422,7 @@ } else { deltaPred = Math.min(deltaPred, wantedIncrement - deltaNext); } - } else { // take as much as possible from pred + } else { // take as much as possible from pred if (deltaPred >= wantedIncrement) { deltaPred = wantedIncrement; deltaNext = 0; @@ -357,6 +430,7 @@ deltaNext = Math.min(deltaNext, wantedIncrement - deltaPred); } } + } else if (deltaNext > 0) { if (deltaNext > wantedIncrement) deltaNext = wantedIncrement;
_______________________________________________ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk https://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev