Changeset 11722 in josm for trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java
- Timestamp:
- 2017-03-13T17:04:29+01:00 (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java
r11719 r11722 75 75 import org.openstreetmap.josm.gui.mappaint.styleelement.MapImage; 76 76 import org.openstreetmap.josm.gui.mappaint.styleelement.NodeElement; 77 import org.openstreetmap.josm.gui.mappaint.styleelement.PositionForAreaStrategy; 77 78 import org.openstreetmap.josm.gui.mappaint.styleelement.RepeatImageElement.LineImageAlignment; 78 79 import org.openstreetmap.josm.gui.mappaint.styleelement.StyleElement; 79 80 import org.openstreetmap.josm.gui.mappaint.styleelement.Symbol; 81 import org.openstreetmap.josm.gui.mappaint.styleelement.TextElement; 80 82 import org.openstreetmap.josm.gui.mappaint.styleelement.TextLabel; 81 83 import org.openstreetmap.josm.tools.CompositeList; … … 400 402 protected void drawArea(OsmPrimitive osm, Path2D.Double path, Color color, 401 403 MapImage fillImage, Float extent, Path2D.Double pfClip, boolean disabled, TextLabel text) { 402 403 Shape area = path.createTransformedShape(mapState.getAffineTransform()); 404 405 if (color.getAlpha() == 0) { 406 // skip drawing 407 } else if (!isOutlineOnly) { 404 if (!isOutlineOnly && color.getAlpha() != 0) { 405 Shape area = path.createTransformedShape(mapState.getAffineTransform()); 408 406 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); 409 407 if (fillImage == null) { … … 451 449 } 452 450 453 drawAreaText(osm, text, area);454 } 455 456 private void drawAreaText(OsmPrimitive osm, TextLabel text, Shape area) {457 if (text != null && isShowNames() ) {451 drawAreaText(osm, text, path); 452 } 453 454 private void drawAreaText(OsmPrimitive osm, TextLabel text, Path2D.Double path) { 455 if (text != null && isShowNames() && isAreaVisible(path)) { 458 456 // abort if we can't compose the label to be rendered 459 457 if (text.labelCompositionStrategy == null) return; … … 461 459 if (name == null || name.isEmpty()) return; 462 460 461 Shape area = path.createTransformedShape(mapState.getAffineTransform()); 463 462 FontMetrics fontMetrics = g.getFontMetrics(orderFont); // if slow, use cache 464 463 Rectangle2D nb = fontMetrics.getStringBounds(name, g); // if slow, approximate by strlen()*maxcharbounds(font) 465 464 466 Rectangle centeredNBounds =findLabelPlacement(area, nb);465 Rectangle2D centeredNBounds = text.getLabelPositionSteategy().findLabelPlacement(area, nb); 467 466 if (centeredNBounds != null) { 468 467 Font defaultFont = g.getFont(); … … 475 474 } 476 475 } 477 }478 479 /**480 * Finds the correct position of a label / icon inside the area.481 * @param area The area to search in482 * @param nb The bounding box of the thing we are searching a place for.483 * @return The position as rectangle with the same dimension as nb. <code>null</code> if none was found.484 */485 private Rectangle findLabelPlacement(Shape area, Rectangle2D nb) {486 // Using the Centroid is Nicer for buildings like: +--------+487 // but this needs to be fast. As most houses are | 42 |488 // boxes anyway, the center of the bounding box +---++---+489 // will have to do. ++490 // Centroids are not optimal either, just imagine a U-shaped house.491 492 Rectangle pb = area.getBounds();493 494 // quick check to see if label box is smaller than primitive box495 if (pb.width < nb.getWidth() || pb.height < nb.getHeight()) {496 return null;497 }498 499 final double w = pb.width - nb.getWidth();500 final double h = pb.height - nb.getHeight();501 502 final int x2 = pb.x + (int) (w/2.0);503 final int y2 = pb.y + (int) (h/2.0);504 505 final int nbw = (int) nb.getWidth();506 final int nbh = (int) nb.getHeight();507 508 Rectangle centeredNBounds = new Rectangle(x2, y2, nbw, nbh);509 510 // slower check to see if label is displayed inside primitive shape511 if (area.contains(centeredNBounds)) {512 return centeredNBounds;513 }514 515 // if center position (C) is not inside osm shape, try naively some other positions as follows:516 // CHECKSTYLE.OFF: SingleSpaceSeparator517 final int x1 = pb.x + (int) (w/4.0);518 final int x3 = pb.x + (int) (3*w/4.0);519 final int y1 = pb.y + (int) (h/4.0);520 final int y3 = pb.y + (int) (3*h/4.0);521 // CHECKSTYLE.ON: SingleSpaceSeparator522 // +-----------+523 // | 5 1 6 |524 // | 4 C 2 |525 // | 8 3 7 |526 // +-----------+527 Rectangle[] candidates = new Rectangle[] {528 new Rectangle(x2, y1, nbw, nbh),529 new Rectangle(x3, y2, nbw, nbh),530 new Rectangle(x2, y3, nbw, nbh),531 new Rectangle(x1, y2, nbw, nbh),532 new Rectangle(x1, y1, nbw, nbh),533 new Rectangle(x3, y1, nbw, nbh),534 new Rectangle(x3, y3, nbw, nbh),535 new Rectangle(x1, y3, nbw, nbh)536 };537 // Dumb algorithm to find a better placement. We could surely find a smarter one but it should538 // solve most of building issues with only few calculations (8 at most)539 for (int i = 0; i < candidates.length; i++) {540 centeredNBounds = candidates[i];541 if (area.contains(centeredNBounds)) {542 return centeredNBounds;543 }544 }545 546 // none found547 return null;548 476 } 549 477 … … 1181 1109 1182 1110 /** 1111 * Draws a text for the given primitive 1112 * @param osm The primitive to draw the text for 1113 * @param text The text definition (font/position/.../text content) to draw. 1114 * @since 11722 1115 */ 1116 public void drawText(OsmPrimitive osm, TextLabel text) { 1117 PositionForAreaStrategy position = text.getLabelPositionSteategy(); 1118 if (position.supportsGlyphVector()) { 1119 if (osm instanceof Way) { 1120 // we might allow this for the outline of relations as well. 1121 drawTextOnPath((Way) osm, text); 1122 } 1123 } else { 1124 if (osm instanceof Way) { 1125 drawAreaText(osm, text, getPath((Way) osm)); 1126 } else if (osm instanceof Relation) { 1127 Multipolygon multipolygon = MultipolygonCache.getInstance().get(nc, (Relation) osm); 1128 if (!multipolygon.getOuterWays().isEmpty()) { 1129 for (PolyData pd : multipolygon.getCombinedPolygons()) { 1130 drawAreaText(osm, text, pd.get()); 1131 } 1132 } 1133 } 1134 } 1135 } 1136 1137 /** 1183 1138 * Draws a text along a given way. 1184 1139 * @param way The way to draw the text on. … … 1822 1777 if (drawMultipolygon && drawArea && s instanceof AreaElement && (flags & FLAG_DISABLED) == 0) { 1823 1778 output.add(new StyleRecord(s, osm, flags)); 1779 } else if (drawMultipolygon && drawArea && s instanceof TextElement) { 1780 output.add(new StyleRecord(s, osm, flags)); 1824 1781 } else if (drawRestriction && s instanceof NodeElement) { 1825 1782 output.add(new StyleRecord(s, osm, flags));
Note:
See TracChangeset
for help on using the changeset viewer.