source: josm/trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/AbstractMapRenderer.java@ 17333

Last change on this file since 17333 was 17333, checked in by Don-vip, 3 years ago

see #20129 - Fix typos and misspellings in the code (patch by gaben)

  • Property svn:eol-style set to native
File size: 10.4 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.osm.visitor.paint;
3
4import java.awt.Color;
5import java.awt.Graphics2D;
6import java.awt.geom.GeneralPath;
7import java.awt.geom.Path2D;
8import java.awt.geom.Rectangle2D;
9import java.util.Iterator;
10
11import org.openstreetmap.josm.data.osm.BBox;
12import org.openstreetmap.josm.data.osm.INode;
13import org.openstreetmap.josm.data.osm.IWay;
14import org.openstreetmap.josm.data.osm.OsmData;
15import org.openstreetmap.josm.data.osm.Way;
16import org.openstreetmap.josm.data.osm.WaySegment;
17import org.openstreetmap.josm.gui.MapViewState;
18import org.openstreetmap.josm.gui.MapViewState.MapViewPoint;
19import org.openstreetmap.josm.gui.MapViewState.MapViewRectangle;
20import org.openstreetmap.josm.gui.NavigatableComponent;
21import org.openstreetmap.josm.spi.preferences.Config;
22import org.openstreetmap.josm.tools.CheckParameterUtil;
23import org.openstreetmap.josm.tools.Logging;
24
25/**
26 * <p>Abstract common superclass for {@link Rendering} implementations.</p>
27 * @since 4087
28 */
29public abstract class AbstractMapRenderer implements Rendering {
30
31 /** the graphics context to which the visitor renders OSM objects */
32 protected final Graphics2D g;
33 /** the map viewport - provides projection and hit detection functionality */
34 protected final NavigatableComponent nc;
35
36 /**
37 * The {@link MapViewState} to use to convert between coordinates.
38 */
39 protected final MapViewState mapState;
40
41 /** if true, the paint visitor shall render OSM objects such that they
42 * look inactive. Example: rendering of data in an inactive layer using light gray as color only. */
43 protected boolean isInactiveMode;
44 /** Color Preference for background */
45 protected Color backgroundColor;
46 /** Color Preference for inactive objects */
47 protected Color inactiveColor;
48 /** Color Preference for selected objects */
49 protected Color selectedColor;
50 /** Color Preference for members of selected relations */
51 protected Color relationSelectedColor;
52 /** Color Preference for nodes */
53 protected Color nodeColor;
54
55 /** Color Preference for highlighted objects */
56 protected Color highlightColor;
57 /** Preference: size of virtual nodes (0 displays display) */
58 protected int virtualNodeSize;
59 /** Preference: minimum space (displayed way length) to display virtual nodes */
60 protected int virtualNodeSpace;
61
62 /** Preference: minimum space (displayed way length) to display segment numbers */
63 protected int segmentNumberSpace;
64
65 /** Performs slow operations by default. Can be disabled when fast partial rendering is required */
66 protected boolean doSlowOperations = true;
67
68 /**
69 * <p>Creates an abstract paint visitor</p>
70 *
71 * @param g the graphics context. Must not be null.
72 * @param nc the map viewport. Must not be null.
73 * @param isInactiveMode if true, the paint visitor shall render OSM objects such that they
74 * look inactive. Example: rendering of data in an inactive layer using light gray as color only.
75 * @throws IllegalArgumentException if {@code g} is null
76 * @throws IllegalArgumentException if {@code nc} is null
77 */
78 protected AbstractMapRenderer(Graphics2D g, NavigatableComponent nc, boolean isInactiveMode) {
79 CheckParameterUtil.ensureParameterNotNull(g);
80 CheckParameterUtil.ensureParameterNotNull(nc);
81 this.g = g;
82 this.nc = nc;
83 this.mapState = nc.getState();
84 this.isInactiveMode = isInactiveMode;
85 }
86
87 /**
88 * Draw the node as small square with the given color.
89 *
90 * @param n The node to draw.
91 * @param color The color of the node.
92 * @param size size in pixels
93 * @param fill determines if the square mmust be filled
94 */
95 public abstract void drawNode(INode n, Color color, int size, boolean fill);
96
97 /**
98 * Draw an number of the order of the two consecutive nodes within the
99 * parents way
100 *
101 * @param p1 First point of the way segment.
102 * @param p2 Second point of the way segment.
103 * @param orderNumber The number of the segment in the way.
104 * @param clr The color to use for drawing the text.
105 * @since 10827
106 */
107 protected void drawOrderNumber(MapViewPoint p1, MapViewPoint p2, int orderNumber, Color clr) {
108 if (isSegmentVisible(p1, p2) && isLargeSegment(p1, p2, segmentNumberSpace)) {
109 String on = Integer.toString(orderNumber);
110 int strlen = on.length();
111 double centerX = (p1.getInViewX()+p2.getInViewX())/2;
112 double centerY = (p1.getInViewY()+p2.getInViewY())/2;
113 double x = centerX - 4*strlen;
114 double y = centerY + 4;
115
116 if (virtualNodeSize != 0 && isLargeSegment(p1, p2, virtualNodeSpace)) {
117 y = centerY - virtualNodeSize - 3;
118 }
119
120 g.setColor(backgroundColor);
121 g.fill(new Rectangle2D.Double(x-1, y-12, 8*strlen+1d, 14));
122 g.setColor(clr);
123 g.drawString(on, (int) x, (int) y);
124 }
125 }
126
127 /**
128 * Draws virtual nodes.
129 *
130 * @param data The data set being rendered.
131 * @param bbox The bounding box being displayed.
132 * @since 13810 (signature)
133 */
134 public void drawVirtualNodes(OsmData<?, ?, ?, ?> data, BBox bbox) {
135 if (virtualNodeSize == 0 || data == null || bbox == null || data.isLocked())
136 return;
137 // print normal virtual nodes
138 GeneralPath path = new GeneralPath();
139 for (IWay<?> osm : data.searchWays(bbox)) {
140 if (osm.isUsable() && !osm.isDisabledAndHidden() && !osm.isDisabled()) {
141 visitVirtual(path, osm);
142 }
143 }
144 g.setColor(nodeColor);
145 g.draw(path);
146 try {
147 // print highlighted virtual nodes. Since only the color changes, simply
148 // drawing them over the existing ones works fine (at least in their current simple style)
149 path = new GeneralPath();
150 for (WaySegment wseg: data.getHighlightedVirtualNodes()) {
151 if (wseg.way.isUsable() && !wseg.way.isDisabled()) {
152 Way tmpWay = wseg.toWay();
153 visitVirtual(path, tmpWay);
154 tmpWay.setNodes(null);
155 }
156 }
157 g.setColor(highlightColor);
158 g.draw(path);
159 } catch (ArrayIndexOutOfBoundsException e) {
160 // Silently ignore any ArrayIndexOutOfBoundsException that may be raised
161 // if the way has changed while being rendered (fix #7979)
162 // TODO: proper solution ?
163 // Idea from bastiK:
164 // avoid the WaySegment class and add another data class with { Way way; Node firstNode, secondNode; int firstIdx; }.
165 // On read, it would first check, if the way still has firstIdx+2 nodes, then check if the corresponding way nodes are still
166 // the same and report changes in a more controlled manner.
167 Logging.trace(e);
168 }
169 }
170
171 /**
172 * Reads the color definitions from preferences. This function is <code>public</code>, so that
173 * color names in preferences can be displayed even without calling the wireframe display before.
174 */
175 public void getColors() {
176 this.backgroundColor = PaintColors.BACKGROUND.get();
177 this.inactiveColor = PaintColors.INACTIVE.get();
178 this.selectedColor = PaintColors.SELECTED.get();
179 this.relationSelectedColor = PaintColors.RELATIONSELECTED.get();
180 this.nodeColor = PaintColors.NODE.get();
181 this.highlightColor = PaintColors.HIGHLIGHT.get();
182 }
183
184 /**
185 * Reads all the settings from preferences. Calls the @{link #getColors}
186 * function.
187 *
188 * @param virtual <code>true</code> if virtual nodes are used
189 */
190 protected void getSettings(boolean virtual) {
191 this.virtualNodeSize = virtual ? Config.getPref().getInt("mappaint.node.virtual-size", 8) / 2 : 0;
192 this.virtualNodeSpace = Config.getPref().getInt("mappaint.node.virtual-space", 70);
193 this.segmentNumberSpace = Config.getPref().getInt("mappaint.segmentnumber.space", 40);
194 getColors();
195 }
196
197 /**
198 * Checks if a way segemnt is large enough for additional information display.
199 *
200 * @param p1 First point of the way segment.
201 * @param p2 Second point of the way segment.
202 * @param space The free space to check against.
203 * @return <code>true</code> if segment is larger than required space
204 * @since 10827
205 */
206 public static boolean isLargeSegment(MapViewPoint p1, MapViewPoint p2, int space) {
207 return p1.oneNormInView(p2) > space;
208 }
209
210 /**
211 * Checks if segment is visible in display.
212 *
213 * @param p1 First point of the way segment.
214 * @param p2 Second point of the way segment.
215 * @return <code>true</code> if segment may be visible.
216 * @since 10827
217 */
218 protected boolean isSegmentVisible(MapViewPoint p1, MapViewPoint p2) {
219 MapViewRectangle view = mapState.getViewArea();
220 // not outside in the same direction
221 return (p1.getOutsideRectangleFlags(view) & p2.getOutsideRectangleFlags(view)) == 0;
222 }
223
224 /**
225 * Creates path for drawing virtual nodes for one way.
226 *
227 * @param path The path to append drawing to.
228 * @param w The ways to draw node for.
229 * @since 10827
230 * @since 13810 (signature)
231 */
232 public void visitVirtual(Path2D path, IWay<?> w) {
233 Iterator<? extends INode> it = w.getNodes().iterator();
234 MapViewPoint lastP = null;
235 while (it.hasNext()) {
236 INode n = it.next();
237 if (n.isLatLonKnown()) {
238 MapViewPoint p = mapState.getPointFor(n);
239 if (lastP != null && isSegmentVisible(lastP, p) && isLargeSegment(lastP, p, virtualNodeSpace)) {
240 double x = (p.getInViewX()+lastP.getInViewX())/2;
241 double y = (p.getInViewY()+lastP.getInViewY())/2;
242 path.moveTo(x-virtualNodeSize, y);
243 path.lineTo(x+virtualNodeSize, y);
244 path.moveTo(x, y-virtualNodeSize);
245 path.lineTo(x, y+virtualNodeSize);
246 }
247 lastP = p;
248 }
249 }
250 }
251
252 /**
253 * Sets whether slow operations such as text rendering must be performed (true by default).
254 * @param enable whether slow operations such as text rendering must be performed
255 * @since 13987
256 */
257 public final void enableSlowOperations(boolean enable) {
258 doSlowOperations = enable;
259 }
260}
Note: See TracBrowser for help on using the repository browser.