| 1157 | protected Point2D getCentroid(Polygon p) |
| 1158 | { |
| 1159 | double cx = 0.0, cy = 0.0, a = 0.0; |
| 1160 | |
| 1161 | // usually requires points[0] == points[npoints] and can then use i+1 instead of j. |
| 1162 | // Faked it slowly using j. If this is really gets used, this should be fixed. |
| 1163 | for (int i = 0; i < p.npoints; i++) { |
| 1164 | int j = i+1 == p.npoints ? 0 : i+1; |
| 1165 | a += (p.xpoints[i] * p.ypoints[j]) - (p.ypoints[i] * p.xpoints[j]); |
| 1166 | cx += (p.xpoints[i] + p.xpoints[j]) * (p.xpoints[i] * p.ypoints[j] - p.ypoints[i] * p.xpoints[j]); |
| 1167 | cy += (p.ypoints[i] + p.ypoints[j]) * (p.xpoints[i] * p.ypoints[j] - p.ypoints[i] * p.xpoints[j]); |
| 1168 | } |
| 1169 | return new Point2D.Double(cx / (3.0*a), cy / (3.0*a)); |
| 1170 | } |
| 1171 | |
| 1172 | protected double getArea(Polygon p) |
| 1173 | { |
| 1174 | double sum = 0.0; |
| 1175 | |
| 1176 | // usually requires points[0] == points[npoints] and can then use i+1 instead of j. |
| 1177 | // Faked it slowly using j. If this is really gets used, this should be fixed. |
| 1178 | for (int i = 0; i < p.npoints; i++) { |
| 1179 | int j = i+1 == p.npoints ? 0 : i+1; |
| 1180 | sum = sum + (p.xpoints[i] * p.ypoints[j]) - (p.ypoints[i] * p.xpoints[j]); |
| 1181 | } |
| 1182 | return Math.abs(sum/2.0); |
| 1183 | } |
| 1184 | |
| 1192 | |
| 1193 | if (showNames > dist) { |
| 1194 | String name = getWayName(w); |
| 1195 | if (name!=null /* && annotate */) { |
| 1196 | Rectangle pb = polygon.getBounds(); |
| 1197 | FontMetrics fontMetrics = g.getFontMetrics(orderFont); // if slow, use cache |
| 1198 | Rectangle2D nb = fontMetrics.getStringBounds(name, g); // if slow, approximate by strlen()*maxcharbounds(font) |
| 1199 | |
| 1200 | // Point2D c = getCentroid(polygon); |
| 1201 | // Using the Centroid is Nicer for buildings like: +--------+ |
| 1202 | // but this needs to be fast. As most houses are | 42 | |
| 1203 | // boxes anyway, the center of the bounding box +---++---+ |
| 1204 | // will have to do. ++ |
| 1205 | // Centroids are not optimal either, just imagine a U-shaped house. |
| 1206 | // Point2D c = new Point2D.Double(pb.x + pb.width / 2.0, pb.y + pb.height / 2.0); |
| 1207 | // Rectangle2D.Double centeredNBounds = |
| 1208 | // new Rectangle2D.Double(c.getX() - nb.getWidth()/2, |
| 1209 | // c.getY() - nb.getHeight()/2, |
| 1210 | // nb.getWidth(), |
| 1211 | // nb.getHeight()); |
| 1212 | |
| 1213 | Rectangle centeredNBounds = new Rectangle(pb.x + (int)((pb.width - nb.getWidth())/2.0), |
| 1214 | pb.y + (int)((pb.height - nb.getHeight())/2.0), |
| 1215 | (int)nb.getWidth(), |
| 1216 | (int)nb.getHeight()); |
| 1217 | |
| 1218 | //// Draw name bounding box for debugging: |
| 1219 | // g.setColor(new Color(255,255,0,128)); |
| 1220 | // g.drawRect((int)centeredNBounds.getMinX(), |
| 1221 | // (int)centeredNBounds.getMinY(), |
| 1222 | // (int)centeredNBounds.getWidth(), |
| 1223 | // (int)centeredNBounds.getHeight()); |
| 1224 | |
| 1225 | if ((pb.width >= nb.getWidth() && pb.height >= nb.getHeight()) && // quick check |
| 1226 | polygon.contains(centeredNBounds) // slow but nice |
| 1227 | ) { |
| 1228 | g.setColor(textColor); |
| 1229 | Font defaultFont = g.getFont(); |
| 1230 | g.setFont (orderFont); |
| 1231 | g.drawString (name, |
| 1232 | (int)(centeredNBounds.getMinX() - nb.getMinX()), |
| 1233 | (int)(centeredNBounds.getMinY() - nb.getMinY())); |
| 1234 | g.setFont(defaultFont); |
| 1235 | } |
| 1236 | } |
| 1237 | } |