source: josm/trunk/src/org/openstreetmap/josm/gui/mappaint/LineElemStyle.java@ 5212

Last change on this file since 5212 was 5212, checked in by bastiK, 12 years ago

minor coding style change

  • Property svn:eol-style set to native
File size: 13.7 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.mappaint;
3
4import static org.openstreetmap.josm.tools.Utils.equal;
5
6import java.awt.BasicStroke;
7import java.awt.Color;
8import java.util.Arrays;
9
10import org.openstreetmap.josm.data.osm.Node;
11import org.openstreetmap.josm.data.osm.OsmPrimitive;
12import org.openstreetmap.josm.data.osm.Way;
13import org.openstreetmap.josm.data.osm.visitor.paint.MapPaintSettings;
14import org.openstreetmap.josm.data.osm.visitor.paint.MapPainter;
15import org.openstreetmap.josm.data.osm.visitor.paint.PaintColors;
16import org.openstreetmap.josm.tools.Utils;
17
18public class LineElemStyle extends ElemStyle {
19
20 public static LineElemStyle createSimpleLineStyle(Color color, boolean isAreaEdge) {
21 MultiCascade mc = new MultiCascade();
22 Cascade c = mc.getOrCreateCascade("default");
23 c.put("width", Keyword.DEFAULT);
24 c.put("color", color != null ? color : PaintColors.UNTAGGED.get());
25 if (isAreaEdge) {
26 c.put("z-index", -3f);
27 }
28 return createLine(new Environment(null, mc, "default", null));
29 }
30 public static final LineElemStyle UNTAGGED_WAY = createSimpleLineStyle(null, false);
31
32 private BasicStroke line;
33 public Color color;
34 public Color dashesBackground;
35 public float offset;
36 public float realWidth; // the real width of this line in meter
37
38 private BasicStroke dashesLine;
39
40 protected enum LineType {
41 NORMAL(""),
42 CASING("casing-"),
43 LEFT_CASING("left-casing-"),
44 RIGHT_CASING("right-casing");
45
46 public String prefix;
47
48 LineType(String prefix) {
49 this.prefix = prefix;
50 }
51 }
52
53 protected LineElemStyle(Cascade c, BasicStroke line, Color color, BasicStroke dashesLine, Color dashesBackground, float offset, float realWidth) {
54 super(c, 0f);
55 this.line = line;
56 this.color = color;
57 this.dashesLine = dashesLine;
58 this.dashesBackground = dashesBackground;
59 this.offset = offset;
60 this.realWidth = realWidth;
61 }
62
63 public static LineElemStyle createLine(Environment env) {
64 return createImpl(env, LineType.NORMAL);
65 }
66
67 public static LineElemStyle createLeftCasing(Environment env) {
68 LineElemStyle leftCasing = createImpl(env, LineType.LEFT_CASING);
69 if (leftCasing != null) {
70 leftCasing.z_index += -90;
71 leftCasing.isModifier = true;
72 }
73 return leftCasing;
74 }
75
76 public static LineElemStyle createRightCasing(Environment env) {
77 LineElemStyle rightCasing = createImpl(env, LineType.RIGHT_CASING);
78 if (rightCasing != null) {
79 rightCasing.z_index += -90;
80 rightCasing.isModifier = true;
81 }
82 return rightCasing;
83 }
84
85 public static LineElemStyle createCasing(Environment env) {
86 LineElemStyle casing = createImpl(env, LineType.CASING);
87 if (casing != null) {
88 casing.z_index += -100;
89 casing.isModifier = true;
90 }
91 return casing;
92 }
93
94 private static LineElemStyle createImpl(Environment env, LineType type) {
95 Cascade c = env.mc.getCascade(env.layer);
96 Cascade c_def = env.mc.getCascade("default");
97 Float widthOnDefault = getWidth(c_def, "width", null);
98 Float width = getWidth(c, "width", widthOnDefault);
99 if (type != LineType.NORMAL) {
100 width = getWidth(c, type.prefix + "width", width);
101 }
102 if (width == null)
103 return null;
104
105 float realWidth = c.get(type.prefix + "real_width", 0f, Float.class);
106 if (realWidth > 0 && MapPaintSettings.INSTANCE.isUseRealWidth()) {
107
108 /* if we have a "width" tag, try use it */
109 String widthTag = env.osm.get("width");
110 if(widthTag == null) {
111 widthTag = env.osm.get("est_width");
112 }
113 if(widthTag != null) {
114 try {
115 realWidth = Float.valueOf(widthTag);
116 }
117 catch(NumberFormatException nfe) {
118 }
119 }
120 }
121
122 Float offsetOnDefault = getWidth(c_def, "offset", null);
123 Float offset = getWidth(c, "offset", offsetOnDefault);
124 if (offset == null) {
125 offset = 0f;
126 }
127 if (type != LineType.NORMAL) {
128 /* pre-calculate an offset */
129 Float base_offset = offset;
130 if (type == LineType.LEFT_CASING || type == LineType.RIGHT_CASING) {
131 Float base_width = getWidth(c, "width", widthOnDefault);
132 if (base_width == null || base_width < 2f) {
133 base_width = 2f;
134 }
135 offset = base_width/2 + width/2;
136 } else {
137 offset = 0f;
138 }
139 /* overwrites (e.g. "4") or adjusts (e.g. "+4") a prefixed -offset */
140 if (getWidth(c, type.prefix + "offset", offset) != null) {
141 offset = getWidth(c, type.prefix + "offset", offset);
142 }
143 /* flip sign for the right-casing-offset */
144 if (type == LineType.RIGHT_CASING) {
145 offset *= -1f;
146 }
147 /* use base_offset as the reference center */
148 offset += base_offset;
149 }
150
151 Color color = c.get(type.prefix + "color", null, Color.class);
152 if (type == LineType.NORMAL && color == null) {
153 color = c.get("fill-color", null, Color.class);
154 }
155 if (color == null) {
156 color = PaintColors.UNTAGGED.get();
157 }
158
159 int alpha = 255;
160 Integer pAlpha = Utils.color_float2int(c.get("opacity", null, Float.class));
161 if (pAlpha != null) {
162 alpha = pAlpha;
163 }
164 color = new Color(color.getRed(), color.getGreen(), color.getBlue(), alpha);
165
166 float[] dashes = c.get(type.prefix + "dashes", null, float[].class);
167 if (dashes != null) {
168 boolean hasPositive = false;
169 for (float f : dashes) {
170 if (f > 0) {
171 hasPositive = true;
172 }
173 if (f < 0) {
174 dashes = null;
175 break;
176 }
177 }
178 if (!hasPositive || (dashes != null && dashes.length == 0)) {
179 dashes = null;
180 }
181 }
182 float dashesOffset = c.get(type.prefix + "dashes-offset", 0f, Float.class);
183 Color dashesBackground = c.get(type.prefix + "dashes-background-color", null, Color.class);
184 if (dashesBackground != null) {
185 pAlpha = Utils.color_float2int(c.get(type.prefix + "dashes-background-opacity", null, Float.class));
186 if (pAlpha != null) {
187 alpha = pAlpha;
188 }
189 dashesBackground = new Color(dashesBackground.getRed(), dashesBackground.getGreen(),
190 dashesBackground.getBlue(), alpha);
191 }
192
193 Integer cap = null;
194 Keyword capKW = c.get(type.prefix + "linecap", null, Keyword.class);
195 if (capKW != null) {
196 if (equal(capKW.val, "none")) {
197 cap = BasicStroke.CAP_BUTT;
198 } else if (equal(capKW.val, "round")) {
199 cap = BasicStroke.CAP_ROUND;
200 } else if (equal(capKW.val, "square")) {
201 cap = BasicStroke.CAP_SQUARE;
202 }
203 }
204 if (cap == null) {
205 cap = dashes != null ? BasicStroke.CAP_BUTT : BasicStroke.CAP_ROUND;
206 }
207
208 Integer join = null;
209 Keyword joinKW = c.get(type.prefix + "linejoin", null, Keyword.class);
210 if (joinKW != null) {
211 if (equal(joinKW.val, "round")) {
212 join = BasicStroke.JOIN_ROUND;
213 } else if (equal(joinKW.val, "miter")) {
214 join = BasicStroke.JOIN_MITER;
215 } else if (equal(joinKW.val, "bevel")) {
216 join = BasicStroke.JOIN_BEVEL;
217 }
218 }
219 if (join == null) {
220 join = BasicStroke.JOIN_ROUND;
221 }
222
223 float miterlimit = c.get(type.prefix + "miterlimit", 10f, Float.class);
224 if (miterlimit < 1f) {
225 miterlimit = 10f;
226 }
227
228 BasicStroke line = new BasicStroke(width, cap, join, miterlimit, dashes, dashesOffset);
229 BasicStroke dashesLine = null;
230
231 if (dashes != null && dashesBackground != null) {
232 float[] dashes2 = new float[dashes.length];
233 System.arraycopy(dashes, 0, dashes2, 1, dashes.length - 1);
234 dashes2[0] = dashes[dashes.length-1];
235 dashesLine = new BasicStroke(width, cap, join, miterlimit, dashes2, dashes2[0] + dashesOffset);
236 }
237
238 return new LineElemStyle(c, line, color, dashesLine, dashesBackground, offset, realWidth);
239 }
240
241 @Override
242 public void paintPrimitive(OsmPrimitive primitive, MapPaintSettings paintSettings, MapPainter painter, boolean selected, boolean member) {
243 Way w = (Way)primitive;
244 /* show direction arrows, if draw.segment.relevant_directions_only is not set,
245 the way is tagged with a direction key
246 (even if the tag is negated as in oneway=false) or the way is selected */
247 boolean showOrientation = !isModifier && (selected || paintSettings.isShowDirectionArrow()) && !paintSettings.isUseRealWidth();
248 boolean showOneway = !isModifier && !selected &&
249 !paintSettings.isUseRealWidth() &&
250 paintSettings.isShowOnewayArrow() && w.hasDirectionKeys();
251 boolean onewayReversed = w.reversedDirection();
252 /* head only takes over control if the option is true,
253 the direction should be shown at all and not only because it's selected */
254 boolean showOnlyHeadArrowOnly = showOrientation && !selected && paintSettings.isShowHeadArrowOnly();
255 Node lastN;
256
257 Color myDashedColor = dashesBackground;
258 BasicStroke myLine = line, myDashLine = dashesLine;
259 if (realWidth > 0 && paintSettings.isUseRealWidth() && !showOrientation) {
260 float myWidth = (int) (100 / (float) (painter.getCircum() / realWidth));
261 if (myWidth < line.getLineWidth()) {
262 myWidth = line.getLineWidth();
263 }
264 myLine = new BasicStroke(myWidth, line.getEndCap(), line.getLineJoin(),
265 line.getMiterLimit(), line.getDashArray(), line.getDashPhase());
266 if (dashesLine != null) {
267 myDashLine = new BasicStroke(myWidth, dashesLine.getEndCap(), dashesLine.getLineJoin(),
268 dashesLine.getMiterLimit(), dashesLine.getDashArray(), dashesLine.getDashPhase());
269 }
270 }
271
272 Color myColor = color;
273 if (selected) {
274 myColor = paintSettings.getSelectedColor(color.getAlpha());
275 } else if (member) {
276 myColor = paintSettings.getRelationSelectedColor(color.getAlpha());
277 } else if(w.isDisabled()) {
278 myColor = paintSettings.getInactiveColor();
279 myDashedColor = paintSettings.getInactiveColor();
280 }
281
282 painter.drawWay(w, myColor, myLine, myDashLine, myDashedColor, offset, showOrientation,
283 showOnlyHeadArrowOnly, showOneway, onewayReversed);
284
285 if(paintSettings.isShowOrderNumber() && !painter.isInactiveMode()) {
286 int orderNumber = 0;
287 lastN = null;
288 for(Node n : w.getNodes()) {
289 if(lastN != null) {
290 orderNumber++;
291 painter.drawOrderNumber(lastN, n, orderNumber, myColor);
292 }
293 lastN = n;
294 }
295 }
296 }
297
298 @Override
299 public boolean isProperLineStyle() {
300 return !isModifier;
301 }
302
303 @Override
304 public boolean equals(Object obj) {
305 if (obj == null || getClass() != obj.getClass())
306 return false;
307 if (!super.equals(obj))
308 return false;
309 final LineElemStyle other = (LineElemStyle) obj;
310 return equal(line, other.line) &&
311 equal(color, other.color) &&
312 equal(dashesLine, other.dashesLine) &&
313 equal(dashesBackground, other.dashesBackground) &&
314 offset == other.offset &&
315 realWidth == other.realWidth;
316 }
317
318 @Override
319 public int hashCode() {
320 int hash = super.hashCode();
321 hash = 29 * hash + line.hashCode();
322 hash = 29 * hash + color.hashCode();
323 hash = 29 * hash + (dashesLine != null ? dashesLine.hashCode() : 0);
324 hash = 29 * hash + (dashesBackground != null ? dashesBackground.hashCode() : 0);
325 hash = 29 * hash + Float.floatToIntBits(offset);
326 hash = 29 * hash + Float.floatToIntBits(realWidth);
327 return hash;
328 }
329
330 @Override
331 public String toString() {
332 return "LineElemStyle{" + super.toString() + "width=" + line.getLineWidth() +
333 " realWidth=" + realWidth + " color=" + Utils.toString(color) +
334 " dashed=" + Arrays.toString(line.getDashArray()) +
335 (line.getDashPhase() == 0f ? "" : " dashesOffses=" + line.getDashPhase()) +
336 " dashedColor=" + Utils.toString(dashesBackground) +
337 " linejoin=" + linejoinToString(line.getLineJoin()) +
338 " linecap=" + linecapToString(line.getEndCap()) +
339 (offset == 0 ? "" : " offset=" + offset) +
340 '}';
341 }
342
343 public String linejoinToString(int linejoin) {
344 switch (linejoin) {
345 case BasicStroke.JOIN_BEVEL: return "bevel";
346 case BasicStroke.JOIN_ROUND: return "round";
347 case BasicStroke.JOIN_MITER: return "miter";
348 default: return null;
349 }
350 }
351 public String linecapToString(int linecap) {
352 switch (linecap) {
353 case BasicStroke.CAP_BUTT: return "none";
354 case BasicStroke.CAP_ROUND: return "round";
355 case BasicStroke.CAP_SQUARE: return "square";
356 default: return null;
357 }
358 }
359}
Note: See TracBrowser for help on using the repository browser.