Changeset 11722 in josm
- Timestamp:
- 2017-03-13T17:04:29+01:00 (8 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 2 added
- 5 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)); -
trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java
r11608 r11722 26 26 import org.openstreetmap.josm.gui.mappaint.styleelement.BoxTextElement; 27 27 import org.openstreetmap.josm.gui.mappaint.styleelement.LineElement; 28 import org.openstreetmap.josm.gui.mappaint.styleelement.LineTextElement;29 28 import org.openstreetmap.josm.gui.mappaint.styleelement.NodeElement; 30 29 import org.openstreetmap.josm.gui.mappaint.styleelement.RepeatImageElement; 31 30 import org.openstreetmap.josm.gui.mappaint.styleelement.StyleElement; 31 import org.openstreetmap.josm.gui.mappaint.styleelement.TextElement; 32 32 import org.openstreetmap.josm.gui.mappaint.styleelement.TextLabel; 33 33 import org.openstreetmap.josm.gui.util.GuiHelper; … … 366 366 env.layer = e.getKey(); 367 367 if (osm instanceof Way) { 368 addIfNotNull(sl, AreaElement.create(env)); 368 AreaElement areaStyle = AreaElement.create(env); 369 addIfNotNull(sl, areaStyle); 369 370 addIfNotNull(sl, RepeatImageElement.create(env)); 370 371 addIfNotNull(sl, LineElement.createLine(env)); … … 372 373 addIfNotNull(sl, LineElement.createRightCasing(env)); 373 374 addIfNotNull(sl, LineElement.createCasing(env)); 374 addIfNotNull(sl, LineTextElement.create(env)); 375 addIfNotNull(sl, TextElement.create(env)); 376 if (areaStyle != null) { 377 //TODO: Warn about this, or even remove it completely 378 addIfNotNull(sl, TextElement.createForContent(env)); 379 } 375 380 } else if (osm instanceof Node) { 376 381 NodeElement nodeStyle = NodeElement.create(env); … … 383 388 } else if (osm instanceof Relation) { 384 389 if (((Relation) osm).isMultipolygon()) { 385 addIfNotNull(sl, AreaElement.create(env)); 390 AreaElement areaStyle = AreaElement.create(env); 391 addIfNotNull(sl, areaStyle); 386 392 addIfNotNull(sl, RepeatImageElement.create(env)); 387 393 addIfNotNull(sl, LineElement.createLine(env)); 388 394 addIfNotNull(sl, LineElement.createCasing(env)); 389 addIfNotNull(sl, LineTextElement.create(env)); 395 addIfNotNull(sl, TextElement.create(env)); 396 if (areaStyle != null) { 397 //TODO: Warn about this, or even remove it completely 398 addIfNotNull(sl, TextElement.createForContent(env)); 399 } 390 400 } else if (osm.hasTag("type", "restriction")) { 391 401 addIfNotNull(sl, NodeElement.create(env)); -
trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/AreaElement.java
r11720 r11722 10 10 import org.openstreetmap.josm.data.osm.Way; 11 11 import org.openstreetmap.josm.data.osm.visitor.paint.MapPaintSettings; 12 import org.openstreetmap.josm.data.osm.visitor.paint.PaintColors;13 12 import org.openstreetmap.josm.data.osm.visitor.paint.StyledMapRenderer; 14 13 import org.openstreetmap.josm.data.preferences.IntegerProperty; 15 14 import org.openstreetmap.josm.gui.mappaint.Cascade; 16 15 import org.openstreetmap.josm.gui.mappaint.Environment; 17 import org.openstreetmap.josm.gui.mappaint.Keyword;18 16 import org.openstreetmap.josm.gui.mappaint.MapPaintStyles.IconReference; 19 17 import org.openstreetmap.josm.gui.util.RotationAngle; … … 120 118 } 121 119 122 TextLabel text = null; 123 Keyword textPos = c.get(TEXT_POSITION, null, Keyword.class); 124 if (textPos == null || "center".equals(textPos.val)) { 125 text = TextLabel.create(env, PaintColors.AREA_TEXT.get(), true); 126 } 120 TextLabel text = null; // <- text is handled by TextElement 127 121 MapImage iconImage = NodeElement.createIcon(env); 128 122 RotationAngle rotationAngle = NodeElement.createRotationAngle(env); 129 123 130 if (iconImage != null || text != null) {124 if (iconImage != null) { 131 125 // fake a transparent color. 132 126 color = new Color(0, 0, 0, 0); -
trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/LineTextElement.java
r9371 r11722 13 13 import org.openstreetmap.josm.gui.mappaint.Keyword; 14 14 15 /** 16 * A text that is only on the line 17 * @deprecated since 11722. To be removed summer 2017 18 */ 19 @Deprecated 15 20 public class LineTextElement extends StyleElement { 16 21 -
trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/TextLabel.java
r11717 r11722 15 15 import org.openstreetmap.josm.gui.mappaint.styleelement.LabelCompositionStrategy.StaticLabelCompositionStrategy; 16 16 import org.openstreetmap.josm.gui.mappaint.styleelement.LabelCompositionStrategy.TagLookupCompositionStrategy; 17 import org.openstreetmap.josm.gui.mappaint.styleelement.PositionForAreaStrategy.CompletelyInsideAreaStrategy; 17 18 import org.openstreetmap.josm.tools.CheckParameterUtil; 18 19 import org.openstreetmap.josm.tools.Utils; … … 54 55 */ 55 56 public Color haloColor; 57 58 /** 59 * The position strategy for this text label. 60 */ 61 private final PositionForAreaStrategy labelPositionSteategy; 56 62 57 63 /** … … 66 72 * @param haloRadius halo radius 67 73 * @param haloColor halo color 68 */ 74 * @deprecated since 11722, To be removed in mid-2017 75 */ 76 @Deprecated 69 77 public TextLabel(LabelCompositionStrategy strategy, Font font, int xOffset, int yOffset, Color color, Float haloRadius, Color haloColor) { 70 CheckParameterUtil.ensureParameterNotNull(font); 71 CheckParameterUtil.ensureParameterNotNull(color); 72 labelCompositionStrategy = strategy; 73 this.font = font; 78 this(strategy, font, xOffset, yOffset, color, haloRadius, haloColor, new CompletelyInsideAreaStrategy()); 79 } 80 81 /** 82 * Creates a new text element 83 * 84 * @param strategy the strategy indicating how the text is composed for a specific {@link OsmPrimitive} to be rendered. 85 * If null, no label is rendered. 86 * @param font the font to be used. Must not be null. 87 * @param xOffset x offset 88 * @param yOffset y offset 89 * @param color the color to be used. Must not be null 90 * @param haloRadius halo radius 91 * @param haloColor halo color 92 * @param labelPositionSteategy The position in the area. 93 */ 94 protected TextLabel(LabelCompositionStrategy strategy, Font font, int xOffset, int yOffset, Color color, Float haloRadius, Color haloColor, PositionForAreaStrategy labelPositionSteategy) { 95 this.labelCompositionStrategy = strategy; 96 this.font = Objects.requireNonNull(font, "font"); 74 97 this.xOffset = xOffset; 75 98 this.yOffset = yOffset; 76 this.color = color;99 this.color = Objects.requireNonNull(color, "color"); 77 100 this.haloRadius = haloRadius; 78 101 this.haloColor = haloColor; 102 this.labelPositionSteategy = Objects.requireNonNull(labelPositionSteategy, "labelPositionSteategy"); 79 103 } 80 104 … … 92 116 this.haloColor = other.haloColor; 93 117 this.haloRadius = other.haloRadius; 118 this.labelPositionSteategy = other.labelPositionSteategy; 119 } 120 121 /** 122 * Copy constructor that changes the position strategy. 123 * 124 * @param other the other element. 125 * @param labelPositionSteategy the position 126 */ 127 private TextLabel(TextLabel other, PositionForAreaStrategy labelPositionSteategy) { 128 this.labelCompositionStrategy = other.labelCompositionStrategy; 129 this.font = other.font; 130 this.xOffset = other.xOffset; 131 this.yOffset = other.yOffset; 132 this.color = other.color; 133 this.haloColor = other.haloColor; 134 this.haloRadius = other.haloRadius; 135 this.labelPositionSteategy = labelPositionSteategy; 94 136 } 95 137 … … 177 219 } 178 220 179 return new TextLabel(strategy, font, (int) xOffset, -(int) yOffset, color, haloRadius, haloColor); 221 Keyword positionKeyword = c.get(AreaElement.TEXT_POSITION, null, Keyword.class); 222 PositionForAreaStrategy position = PositionForAreaStrategy.forKeyword(positionKeyword); 223 224 return new TextLabel(strategy, font, (int) xOffset, -(int) yOffset, color, haloRadius, haloColor, position); 180 225 } 181 226 … … 190 235 if (labelCompositionStrategy == null) return null; 191 236 return labelCompositionStrategy.compose(osm); 237 } 238 239 /** 240 * Gets the strategy that defines where to place the label. 241 * @return The strategy. Never null. 242 * @since 11722 243 */ 244 public PositionForAreaStrategy getLabelPositionSteategy() { 245 return labelPositionSteategy; 246 } 247 248 public TextLabel withPosition(PositionForAreaStrategy labelPositionSteategy) { 249 return new TextLabel(this, labelPositionSteategy); 192 250 } 193 251
Note:
See TracChangeset
for help on using the changeset viewer.