source: josm/trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/AreaElement.java@ 11670

Last change on this file since 11670 was 11670, checked in by michael2402, 8 years ago

See #10176: Make icon-image work for areas. Icon is displayed at center of lat/lon bounds.

  • Property svn:eol-style set to native
File size: 7.5 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.mappaint.styleelement;
3
4import java.awt.Color;
5import java.util.Objects;
6
7import org.openstreetmap.josm.Main;
8import org.openstreetmap.josm.data.osm.OsmPrimitive;
9import org.openstreetmap.josm.data.osm.Relation;
10import org.openstreetmap.josm.data.osm.Way;
11import org.openstreetmap.josm.data.osm.visitor.paint.MapPaintSettings;
12import org.openstreetmap.josm.data.osm.visitor.paint.PaintColors;
13import org.openstreetmap.josm.data.osm.visitor.paint.StyledMapRenderer;
14import org.openstreetmap.josm.gui.mappaint.Cascade;
15import org.openstreetmap.josm.gui.mappaint.Environment;
16import org.openstreetmap.josm.gui.mappaint.Keyword;
17import org.openstreetmap.josm.gui.mappaint.MapPaintStyles.IconReference;
18import org.openstreetmap.josm.gui.util.RotationAngle;
19import org.openstreetmap.josm.tools.CheckParameterUtil;
20import org.openstreetmap.josm.tools.Utils;
21
22/**
23 * This is the style that defines how an area is filled.
24 */
25public class AreaElement extends StyleElement {
26
27 /**
28 * If fillImage == null, color is the fill-color, otherwise
29 * an arbitrary color value sampled from the fillImage
30 */
31 public Color color;
32
33 /**
34 * An image to cover this area. May be null to disable this feature.
35 */
36 public MapImage fillImage;
37
38 /**
39 * The text that should be written on this area.
40 */
41 public TextLabel text;
42
43 /**
44 * Fill the area only partially from the borders
45 * <p>
46 * Public access is discouraged.
47 * @see StyledMapRenderer#drawArea(Way, Color, MapImage, Float, Float, boolean, TextLabel)
48 */
49 public Float extent;
50
51 /**
52 * Areas smaller than this are filled no matter what value {@link #extent} has.
53 * <p>
54 * Public access is discouraged.
55 * @see StyledMapRenderer#drawArea(Way, Color, MapImage, Float, Float, boolean, TextLabel)
56 */
57 public Float extentThreshold;
58
59 /**
60 * The icon that is displayed on the center of the area.
61 */
62 private final MapImage iconImage;
63
64 private final RotationAngle iconImageAngle;
65
66 protected AreaElement(Cascade c, Color color, MapImage fillImage, Float extent, Float extentThreshold, TextLabel text, MapImage iconImage, RotationAngle iconImageAngle) {
67 super(c, 1f);
68 CheckParameterUtil.ensureParameterNotNull(color);
69 this.color = color;
70 this.fillImage = fillImage;
71 this.extent = extent;
72 this.extentThreshold = extentThreshold;
73 this.text = text;
74 this.iconImage = iconImage;
75 this.iconImageAngle = iconImageAngle;
76 }
77
78 /**
79 * Create a new {@link AreaElement}
80 * @param env The current style definitions
81 * @return The area element or <code>null</code> if the area should not be filled.
82 */
83 public static AreaElement create(final Environment env) {
84 final Cascade c = env.mc.getCascade(env.layer);
85 MapImage fillImage = null;
86 Color color;
87
88 IconReference iconRef = c.get(FILL_IMAGE, null, IconReference.class);
89 if (iconRef != null) {
90 fillImage = new MapImage(iconRef.iconName, iconRef.source, false);
91
92 color = new Color(fillImage.getImage(false).getRGB(
93 fillImage.getWidth() / 2, fillImage.getHeight() / 2)
94 );
95
96 fillImage.alpha = Math.min(255, Math.max(0, Main.pref.getInteger("mappaint.fill-image-alpha", 255)));
97 Integer pAlpha = Utils.colorFloat2int(c.get(FILL_OPACITY, null, float.class));
98 if (pAlpha != null) {
99 fillImage.alpha = pAlpha;
100 }
101 } else {
102 color = c.get(FILL_COLOR, null, Color.class);
103 if (color != null) {
104 int alpha = color.getAlpha();
105 if (alpha == 255) {
106 // Assume alpha value has not been specified by the user if
107 // is set to fully opaque. Use default value in this case.
108 // It is not an ideal solution, but a little tricky to get this
109 // right, especially as named map colors can be changed in
110 // the preference GUI and written to the preferences file.
111 alpha = Math.min(255, Math.max(0, Main.pref.getInteger("mappaint.fillalpha", 50)));
112 }
113 Integer pAlpha = Utils.colorFloat2int(c.get(FILL_OPACITY, null, float.class));
114 if (pAlpha != null) {
115 alpha = pAlpha;
116 }
117 color = new Color(color.getRed(), color.getGreen(), color.getBlue(), alpha);
118 }
119 }
120
121 if (color != null) {
122
123 TextLabel text = null;
124 Keyword textPos = c.get(TEXT_POSITION, null, Keyword.class);
125 if (textPos == null || "center".equals(textPos.val)) {
126 text = TextLabel.create(env, PaintColors.AREA_TEXT.get(), true);
127 }
128
129 Float extent = c.get(FILL_EXTENT, null, float.class);
130 Float extentThreshold = c.get(FILL_EXTENT_THRESHOLD, null, float.class);
131
132 MapImage iconImage = NodeElement.createIcon(env);
133 RotationAngle rotationAngle = NodeElement.createRotationAngle(env);
134
135 return new AreaElement(c, color, fillImage, extent, extentThreshold, text, iconImage, rotationAngle);
136 } else {
137 return null;
138 }
139 }
140
141 @Override
142 public void paintPrimitive(OsmPrimitive osm, MapPaintSettings paintSettings, StyledMapRenderer painter,
143 boolean selected, boolean outermember, boolean member) {
144 Color myColor = color;
145 if (osm instanceof Way) {
146 if (color != null) {
147 if (selected) {
148 myColor = paintSettings.getSelectedColor(color.getAlpha());
149 } else if (outermember) {
150 myColor = paintSettings.getRelationSelectedColor(color.getAlpha());
151 }
152 }
153 painter.drawArea((Way) osm, myColor, fillImage, extent, extentThreshold, painter.isInactiveMode() || osm.isDisabled(), text);
154 } else if (osm instanceof Relation) {
155 if (color != null && (selected || outermember)) {
156 myColor = paintSettings.getRelationSelectedColor(color.getAlpha());
157 }
158 painter.drawArea((Relation) osm, myColor, fillImage, extent, extentThreshold, painter.isInactiveMode() || osm.isDisabled(), text);
159 }
160
161 if (iconImage != null && painter.isShowIcons()) {
162 painter.drawAreaIcon(osm, iconImage, painter.isInactiveMode() || osm.isDisabled(), selected, member,
163 iconImageAngle == null ? 0.0 : iconImageAngle.getRotationAngle(osm));
164 }
165 }
166
167 @Override
168 public boolean equals(Object obj) {
169 if (this == obj) return true;
170 if (obj == null || getClass() != obj.getClass()) return false;
171 if (!super.equals(obj)) return false;
172 AreaElement that = (AreaElement) obj;
173 return Objects.equals(color, that.color) &&
174 Objects.equals(fillImage, that.fillImage) &&
175 Objects.equals(text, that.text) &&
176 Objects.equals(extent, that.extent) &&
177 Objects.equals(extentThreshold, that.extentThreshold);
178 }
179
180 @Override
181 public int hashCode() {
182 return Objects.hash(super.hashCode(), color, fillImage, text, extent, extentThreshold);
183 }
184
185 @Override
186 public String toString() {
187 return "AreaElemStyle{" + super.toString() + "color=" + Utils.toString(color) +
188 " fillImage=[" + fillImage + "]}";
189 }
190}
Note: See TracBrowser for help on using the repository browser.