 Timestamp:
 20140830T20:14:19+02:00 (5 years ago)
 File:

 1 edited
Legend:
 Unmodified
 Added
 Removed

trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java
r7459 r7471 1049 1049 return; 1050 1050 1051 FontMetrics fontMetrics = g.getFontMetrics(text.font); 1052 Rectangle2D rec = fontMetrics.getStringBounds(name, g); 1053 1054 Rectangle bounds = g.getClipBounds(); 1055 1051 1056 Polygon poly = new Polygon(); 1052 1057 Point lastPoint = null; … … 1054 1059 double pathLength = 0; 1055 1060 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 1056 1068 while (it.hasNext()) { 1057 1069 Node n = it.next(); … … 1062 1074 dx = p.x  lastPoint.x; 1063 1075 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; 1065 1104 } 1066 1105 lastPoint = p; 1067 1106 } 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 1072 1108 if (rec.getWidth() > pathLength) 1073 1109 return; 1074 1110 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 halfsegment > 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; 1077 1157 1078 1158 double[] p1 = pointAt(t1, poly, pathLength);
Note: See TracChangeset
for help on using the changeset viewer.