Ignore:
Timestamp:
2014-08-30T20:14:19+02:00 (10 years ago)
Author:
bastiK
Message:

fixed #10383 - nodes hidden by street name

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java

    r7459 r7471  
    10491049            return;
    10501050
     1051        FontMetrics fontMetrics = g.getFontMetrics(text.font);
     1052        Rectangle2D rec = fontMetrics.getStringBounds(name, g);
     1053
     1054        Rectangle bounds = g.getClipBounds();
     1055       
    10511056        Polygon poly = new Polygon();
    10521057        Point lastPoint = null;
     
    10541059        double pathLength = 0;
    10551060        long dx, dy;
     1061       
     1062        // find half segments that are long enough to draw text on
     1063        // (don't draw text over the cross hair in the center of each segment)
     1064        List<Double> longHalfSegmentSart = new ArrayList<>(); // start point of half segment (as length along the way)
     1065        List<Double> longHalfSegmentEnd = new ArrayList<>(); // end point of half segment (as length along the way)
     1066        List<Double> longHalfsegmentQuality = new ArrayList<>(); // quality factor (off screen / partly on screen / fully on screen)
     1067       
    10561068        while (it.hasNext()) {
    10571069            Node n = it.next();
     
    10621074                dx = p.x - lastPoint.x;
    10631075                dy = p.y - lastPoint.y;
    1064                 pathLength += Math.sqrt(dx*dx + dy*dy);
     1076                double segmentLength = Math.sqrt(dx*dx + dy*dy);
     1077                if (segmentLength > 2*(rec.getWidth()+4)) {
     1078                    Point center = new Point((lastPoint.x + p.x)/2, (lastPoint.y + p.y)/2);
     1079                    double q = 0;
     1080                    if (bounds != null) {
     1081                        if (bounds.contains(lastPoint) && bounds.contains(center)) {
     1082                            q = 2;
     1083                        } else if (bounds.contains(lastPoint) || bounds.contains(center)) {
     1084                            q = 1;
     1085                        }
     1086                    }
     1087                    longHalfSegmentSart.add(pathLength);
     1088                    longHalfSegmentEnd.add(pathLength + segmentLength / 2);
     1089                    longHalfsegmentQuality.add(q);
     1090                   
     1091                    q = 0;
     1092                    if (bounds != null) {
     1093                        if (bounds.contains(center) && bounds.contains(p)) {
     1094                            q = 2;
     1095                        } else if (bounds.contains(center) || bounds.contains(p)) {
     1096                            q = 1;
     1097                        }
     1098                    }
     1099                    longHalfSegmentSart.add(pathLength + segmentLength / 2);
     1100                    longHalfSegmentEnd.add(pathLength + segmentLength);
     1101                    longHalfsegmentQuality.add(q);
     1102                }
     1103                pathLength += segmentLength;
    10651104            }
    10661105            lastPoint = p;
    10671106        }
    1068 
    1069         FontMetrics fontMetrics = g.getFontMetrics(text.font); // if slow, use cache
    1070         Rectangle2D rec = fontMetrics.getStringBounds(name, g); // if slow, approximate by strlen()*maxcharbounds(font)
    1071 
     1107       
    10721108        if (rec.getWidth() > pathLength)
    10731109            return;
    10741110
    1075         double t1 = (pathLength/2 - rec.getWidth()/2) / pathLength;
    1076         double t2 = (pathLength/2 + rec.getWidth()/2) / pathLength;
     1111        double t1, t2;
     1112       
     1113        if (!longHalfSegmentSart.isEmpty()) {
     1114            if (way.getNodesCount() == 2) {
     1115                // For 2 node ways, the two half segments are exactly
     1116                // the same size and distance from the center.
     1117                // Prefer the first one for consistency.
     1118                longHalfsegmentQuality.set(0, longHalfsegmentQuality.get(0) + 0.5);
     1119            }
     1120           
     1121            // find the long half segment that is closest to the center of the way
     1122            // candidates with higher quality value are preferred
     1123            double bestStart = Double.NaN;
     1124            double bestEnd = Double.NaN;
     1125            double bestDistanceToCenter = Double.MAX_VALUE;
     1126            double bestQuality = -1;
     1127            for (int i=0; i<longHalfSegmentSart.size(); i++) {
     1128                double start = longHalfSegmentSart.get(i);
     1129                double end = longHalfSegmentEnd.get(i);
     1130                double dist = Math.abs(0.5 * (end + start) - 0.5 * pathLength);
     1131                if (longHalfsegmentQuality.get(i) > bestQuality || (dist < bestDistanceToCenter && longHalfsegmentQuality.get(i) == bestQuality)) {
     1132                    bestStart = start;
     1133                    bestEnd = end;
     1134                    bestDistanceToCenter = dist;
     1135                    bestQuality = longHalfsegmentQuality.get(i);
     1136                }
     1137            }
     1138            double remaining = bestEnd - bestStart - rec.getWidth(); // total space left and right from the text
     1139            // The space left and right of the text should be distributed 20% - 80% (towards the center),
     1140            // but the smaller space should not be less than 7 px.
     1141            // However, if the total remaining space is less than 14 px, then distribute it evenly.
     1142            double smallerSpace = Math.min(Math.max(0.2 * remaining, 7), 0.5 * remaining);
     1143            if ((bestEnd + bestStart)/2 < pathLength/2) {
     1144                t2 = bestEnd - smallerSpace;
     1145                t1 = t2 - rec.getWidth();
     1146            } else {
     1147                t1 = bestStart + smallerSpace;
     1148                t2 = t1 + rec.getWidth();
     1149            }
     1150        } else {
     1151            // doesn't fit into one half-segment -> just put it in the center of the way
     1152            t1 = pathLength/2 - rec.getWidth()/2;
     1153            t2 = pathLength/2 + rec.getWidth()/2;
     1154        }
     1155        t1 /= pathLength;
     1156        t2 /= pathLength;
    10771157
    10781158        double[] p1 = pointAt(t1, poly, pathLength);
Note: See TracChangeset for help on using the changeset viewer.