source: josm/trunk/src/org/openstreetmap/josm/data/osm/visitor/SimplePaintVisitor.java@ 610

Last change on this file since 610 was 610, checked in by framm, 16 years ago
  • fix "getting started" screen for low resolutions
  • fix incompatibility with validator plugin
File size: 7.3 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.data.osm.visitor;
3
4import java.awt.Color;
5import java.awt.Graphics;
6import java.awt.Graphics2D;
7import java.awt.Point;
8import java.awt.Rectangle;
9import java.awt.geom.GeneralPath;
10
11import java.util.Iterator;
12import org.openstreetmap.josm.Main;
13import org.openstreetmap.josm.data.Preferences;
14import org.openstreetmap.josm.data.osm.DataSet;
15import org.openstreetmap.josm.data.osm.Relation;
16import org.openstreetmap.josm.data.osm.Node;
17import org.openstreetmap.josm.data.osm.OsmPrimitive;
18import org.openstreetmap.josm.data.osm.Way;
19import org.openstreetmap.josm.gui.NavigatableComponent;
20import org.openstreetmap.josm.tools.ColorHelper;
21
22/**
23 * A visitor that paints a simple scheme of every primitive it visits to a
24 * previous set graphic environment.
25 *
26 * @author imi
27 */
28public class SimplePaintVisitor implements Visitor {
29
30 public final static Color darkerblue = new Color(0,0,96);
31 public final static Color darkblue = new Color(0,0,128);
32 public final static Color darkgreen = new Color(0,128,0);
33
34 /**
35 * The environment to paint to.
36 */
37 protected Graphics g;
38 /**
39 * MapView to get screen coordinates.
40 */
41 protected NavigatableComponent nc;
42
43 public boolean inactive;
44
45 protected static final double PHI = Math.toRadians(20);
46
47 /**
48 * Preferences
49 */
50 protected Color inactiveColor;
51 protected Color selectedColor;
52 protected Color nodeColor;
53 protected Color dfltWayColor;
54 protected Color untaggedWayColor;
55 protected Color incompleteColor;
56 protected Color backgroundColor;
57 protected boolean showDirectionArrow;
58 protected boolean showRelevantDirectionsOnly;
59 protected boolean showOrderNumber;
60
61 /**
62 * Draw subsequent segments of same color as one Path
63 */
64 protected Color currentColor = null;
65 protected GeneralPath currentPath = new GeneralPath();
66
67 private Rectangle screen;
68 Rectangle bbox = new Rectangle();
69
70 public void visitAll(DataSet data) {
71 inactiveColor = Preferences.getPreferencesColor("inactive", Color.DARK_GRAY);
72 selectedColor = Preferences.getPreferencesColor("selected", Color.WHITE);
73 nodeColor = Preferences.getPreferencesColor("node", Color.RED);
74 dfltWayColor = Preferences.getPreferencesColor("way", darkblue);
75 untaggedWayColor = Preferences.getPreferencesColor("untagged way", darkgreen);
76 incompleteColor = Preferences.getPreferencesColor("incomplete way", darkerblue);
77 backgroundColor = Preferences.getPreferencesColor("background", Color.BLACK);
78 showDirectionArrow = Main.pref.getBoolean("draw.segment.direction");
79 showRelevantDirectionsOnly = Main.pref.getBoolean("draw.segment.relevant_directions_only");
80 showOrderNumber = Main.pref.getBoolean("draw.segment.order_number");
81
82 // draw tagged ways first, then untagged ways. takes
83 // time to iterate through list twice, OTOH does not
84 // require changing the colour while painting...
85 for (final OsmPrimitive osm : data.ways)
86 if (!osm.deleted && !osm.selected && osm.tagged)
87 osm.visit(this);
88 displaySegments(null);
89
90 for (final OsmPrimitive osm : data.ways)
91 if (!osm.deleted && !osm.selected && !osm.tagged)
92 osm.visit(this);
93 displaySegments(null);
94
95 for (final OsmPrimitive osm : data.nodes)
96 if (!osm.deleted && !osm.selected)
97 osm.visit(this);
98
99 for (final OsmPrimitive osm : data.getSelected())
100 if (!osm.deleted)
101 osm.visit(this);
102 displaySegments(null);
103 }
104
105 /**
106 * Draw a small rectangle.
107 * White if selected (as always) or red otherwise.
108 *
109 * @param n The node to draw.
110 */
111 public void visit(Node n) {
112 if (n.incomplete) return;
113
114 Color color = null;
115 if (inactive)
116 color = inactiveColor;
117 else if (n.selected)
118 color = selectedColor;
119 else
120 color = nodeColor;
121 drawNode(n, color);
122 }
123
124 /**
125 * Draw a darkblue line for all segments.
126 * @param w The way to draw.
127 */
128 public void visit(Way w) {
129 if (w.incomplete) return;
130
131 // show direction arrows, if draw.segment.relevant_directions_only is not set, the way is tagged with a direction key
132 // (even if the tag is negated as in oneway=false) or the way is selected
133
134 boolean showThisDirectionArrow = w.selected
135 || (showDirectionArrow
136 && (!showRelevantDirectionsOnly || w.hasDirectionKeys));
137 Color wayColor;
138
139 if (inactive) {
140 wayColor = inactiveColor;
141 } else if (!w.tagged) {
142 wayColor = untaggedWayColor;
143 } else {
144 wayColor = dfltWayColor;
145 }
146
147 Iterator<Node> it = w.nodes.iterator();
148 if (it.hasNext()) {
149 Point lastP = nc.getPoint(it.next().eastNorth);
150 for (int orderNumber = 1; it.hasNext(); orderNumber++) {
151 Point p = nc.getPoint(it.next().eastNorth);
152 drawSegment(lastP, p, w.selected && !inactive ? selectedColor : wayColor, showThisDirectionArrow);
153 if (showOrderNumber)
154 drawOrderNumber(lastP, p, orderNumber);
155 lastP = p;
156 }
157 }
158 }
159
160 public void visit(Relation e) {
161 // relations are not (yet?) drawn.
162 }
163
164 /**
165 * Draw an number of the order of the two consecutive nodes within the
166 * parents way
167 */
168 protected void drawOrderNumber(Point p1, Point p2, int orderNumber) {
169 int strlen = (""+orderNumber).length();
170 int x = (p1.x+p2.x)/2 - 4*strlen;
171 int y = (p1.y+p2.y)/2 + 4;
172
173 if (screen.contains(x,y)) {
174 Color c = g.getColor();
175 g.setColor(backgroundColor);
176 g.fillRect(x-1, y-12, 8*strlen+1, 14);
177 g.setColor(c);
178 g.drawString(""+orderNumber, x, y);
179 }
180 }
181
182 /**
183 * Draw the node as small rectangle with the given color.
184 *
185 * @param n The node to draw.
186 * @param color The color of the node.
187 */
188 public void drawNode(Node n, Color color) {
189 Point p = nc.getPoint(n.eastNorth);
190 g.setColor(color);
191
192 if (screen.contains(p.x, p.y))
193 if (n.tagged) {
194 g.drawRect(p.x, p.y, 0, 0);
195 g.drawRect(p.x-2, p.y-2, 4, 4);
196 } else {
197 g.drawRect(p.x-1, p.y-1, 2, 2);
198 }
199 }
200
201 /**
202 * Draw a line with the given color.
203 */
204 protected void drawSegment(Point p1, Point p2, Color col, boolean showDirection) {
205
206 if (col != currentColor) displaySegments(col);
207
208 if (onScreen(p1, p2)) {
209 currentPath.moveTo(p1.x, p1.y);
210 currentPath.lineTo(p2.x, p2.y);
211
212 if (showDirection) {
213 double t = Math.atan2(p2.y-p1.y, p2.x-p1.x) + Math.PI;
214 currentPath.lineTo((int)(p2.x + 10*Math.cos(t-PHI)), (int)(p2.y + 10*Math.sin(t-PHI)));
215 currentPath.moveTo((int)(p2.x + 10*Math.cos(t+PHI)), (int)(p2.y + 10*Math.sin(t+PHI)));
216 currentPath.lineTo(p2.x, p2.y);
217 }
218 }
219 }
220
221 private boolean onScreen(Point p1, Point p2) {
222 bbox.setBounds(p1.x, p1.y, 0, 0);
223 bbox.add(p2);
224 if (bbox.height + bbox.width < 1) return false;
225 bbox.width++;
226 bbox.height++;
227 return screen.intersects(bbox);
228 }
229
230 public void setGraphics(Graphics g) {
231 this.g = g;
232 screen = g.getClipBounds();
233 }
234
235 public void setNavigatableComponent(NavigatableComponent nc) {
236 this.nc = nc;
237 }
238
239 protected void displaySegments(Color newColor) {
240 if (currentPath != null) {
241 g.setColor(currentColor);
242 ((Graphics2D) g).draw(currentPath);
243 currentPath = new GeneralPath();
244 currentColor = newColor;
245 }
246 }
247
248 /**
249 * Provided for backwards compatibility only.
250 * FIXME: remove this once not used by plugins any longer.
251 */
252 public static Color getPreferencesColor(String name, Color dflt) {
253 return Preferences.getPreferencesColor(name, dflt);
254 }
255}
Note: See TracBrowser for help on using the repository browser.