source: josm/trunk/src/org/openstreetmap/josm/gui/mappaint/Environment.java

Last change on this file was 19336, checked in by stoecker, 15 months ago

fix #24046 - improve speed of multipolygon validator - patch by taylor.smock

  • Property svn:eol-style set to native
File size: 12.1 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.mappaint;
3
4import java.awt.geom.Area;
5import java.util.LinkedHashSet;
6import java.util.List;
7import java.util.Map;
8import java.util.Set;
9
10import org.openstreetmap.josm.data.osm.IPrimitive;
11import org.openstreetmap.josm.data.osm.IRelation;
12import org.openstreetmap.josm.data.osm.MultipolygonBuilder;
13import org.openstreetmap.josm.data.osm.Relation;
14import org.openstreetmap.josm.data.osm.Way;
15import org.openstreetmap.josm.data.osm.WaySegment;
16import org.openstreetmap.josm.gui.mappaint.mapcss.Condition.Context;
17import org.openstreetmap.josm.gui.mappaint.mapcss.Selector;
18import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.LinkSelector;
19import org.openstreetmap.josm.tools.CheckParameterUtil;
20import org.openstreetmap.josm.tools.Pair;
21
22/**
23 * Environment is a data object to provide access to various "global" parameters.
24 * It is used during processing of MapCSS rules and for the generation of
25 * style elements.
26 */
27public class Environment {
28
29 /**
30 * The primitive that is currently evaluated
31 */
32 public IPrimitive osm;
33
34 /**
35 * The cascades that are currently evaluated
36 */
37 public MultiCascade mc;
38 /**
39 * The current MapCSS layer
40 */
41 public String layer;
42 /**
43 * The style source that is evaluated
44 */
45 public StyleSource source;
46 private Context context = Context.PRIMITIVE;
47
48 /** The selector that is currently being evaluated */
49 private final Selector selector;
50
51 /**
52 * The name of the default layer. It is used if no layer is specified in the MapCSS rule
53 */
54 public static final String DEFAULT_LAYER = "default";
55
56 /**
57 * If not null, this is the matching parent object if a condition or an expression
58 * is evaluated in a {@link LinkSelector} (within a child selector)
59 */
60 public IPrimitive parent;
61
62 /**
63 * The same for parent selector. Only one of the 2 fields (parent or child) is not null in any environment.
64 */
65 public IPrimitive child;
66
67 /**
68 * index of node in parent way or member in parent relation. Must be != null in LINK context.
69 */
70 public Integer index;
71
72 /**
73 * count of nodes in parent way or members in parent relation. Must be != null in LINK context.
74 */
75 public Integer count;
76
77 /**
78 * Set of matched children filled by ContainsFinder and CrossingFinder, null if nothing matched
79 */
80 public Set<IPrimitive> children;
81
82 /**
83 * Crossing ways result from CrossingFinder, filled for incomplete ways/relations
84 */
85 public Map<IPrimitive, Map<List<Way>, List<WaySegment>>> crossingWaysMap;
86
87 /**
88 * Intersection areas (only filled with CrossingFinder if children is not null)
89 */
90 public Map<IPrimitive, Area> intersections;
91
92 /**
93 * Cache for multipolygon areas, can be null, used with CrossingFinder
94 */
95 public Map<IPrimitive, Area> mpAreaCache;
96 /**
97 * Cache for multipolygon areas as calculated by {@link MultipolygonBuilder#joinWays(Relation)}, can be {@code null}
98 */
99 public Map<IRelation<?>, Pair<List<MultipolygonBuilder.JoinedPolygon>, List<MultipolygonBuilder.JoinedPolygon>>> mpJoinedAreaCache;
100
101 /**
102 * Can be null, may contain primitives when surrounding objects of the primitives are tested
103 */
104 public Set<IPrimitive> toMatchForSurrounding;
105
106 /**
107 * Creates a new uninitialized environment.
108 */
109 public Environment() {
110 // environment can be initialized later through with* methods
111 this.selector = null;
112 }
113
114 /**
115 * Creates a new environment.
116 * @param osm OSM primitive
117 * @since 8415
118 * @since 13810 (signature)
119 */
120 public Environment(IPrimitive osm) {
121 this(osm, null, null, null);
122 }
123
124 /**
125 * Creates a new environment.
126 * @param osm OSM primitive
127 * @param mc multi cascade
128 * @param layer layer
129 * @param source style source
130 * @since 13810 (signature)
131 */
132 public Environment(IPrimitive osm, MultiCascade mc, String layer, StyleSource source) {
133 this.osm = osm;
134 this.mc = mc;
135 this.layer = layer;
136 this.source = source;
137 this.selector = null;
138 }
139
140 /**
141 * Creates a clone of the environment {@code other}.
142 *
143 * @param other the other environment. Must not be null.
144 * @throws IllegalArgumentException if {@code param} is {@code null}
145 */
146 public Environment(Environment other) {
147 this(other, other.selector);
148 }
149
150 /**
151 * Creates a clone of the environment {@code other}.
152 *
153 * @param other the other environment. Must not be null.
154 * @param selector the selector for this environment. May be null.
155 * @throws IllegalArgumentException if {@code param} is {@code null}
156 */
157 private Environment(Environment other, Selector selector) {
158 CheckParameterUtil.ensureParameterNotNull(other);
159 this.osm = other.osm;
160 this.mc = other.mc;
161 this.layer = other.layer;
162 this.parent = other.parent;
163 this.child = other.child;
164 this.source = other.source;
165 this.index = other.index;
166 this.count = other.count;
167 this.context = other.getContext();
168 this.children = other.children == null ? null : new LinkedHashSet<>(other.children);
169 this.intersections = other.intersections;
170 this.crossingWaysMap = other.crossingWaysMap;
171 this.mpAreaCache = other.mpAreaCache;
172 this.mpJoinedAreaCache = other.mpJoinedAreaCache;
173 this.toMatchForSurrounding = other.toMatchForSurrounding;
174 this.selector = selector;
175 }
176
177 /**
178 * Creates a clone of this environment, with the specified primitive.
179 * @param osm OSM primitive
180 * @return A clone of this environment, with the specified primitive
181 * @see #osm
182 * @since 13810 (signature)
183 */
184 public Environment withPrimitive(IPrimitive osm) {
185 Environment e = new Environment(this);
186 e.osm = osm;
187 return e;
188 }
189
190 /**
191 * Creates a clone of this environment, with the specified parent.
192 * @param parent the matching parent object
193 * @return A clone of this environment, with the specified parent
194 * @see #parent
195 * @since 13810 (signature)
196 */
197 public Environment withParent(IPrimitive parent) {
198 Environment e = new Environment(this);
199 e.parent = parent;
200 return e;
201 }
202
203 /**
204 * Creates a clone of this environment, with the specified parent, index, and context set to {@link Context#LINK}.
205 * @param parent the matching parent object
206 * @param index index of node in parent way or member in parent relation
207 * @param count count of nodes in parent way or members in parent relation
208 * @return A clone of this environment, with the specified parent, index, and context set to {@link Context#LINK}
209 * @see #parent
210 * @see #index
211 * @since 6175
212 * @since 13810 (signature)
213 */
214 public Environment withParentAndIndexAndLinkContext(IPrimitive parent, int index, int count) {
215 Environment e = new Environment(this);
216 e.parent = parent;
217 e.index = index;
218 e.count = count;
219 e.context = Context.LINK;
220 return e;
221 }
222
223 /**
224 * Creates a clone of this environment, with the specified child.
225 * @param child the matching child object
226 * @return A clone of this environment, with the specified child
227 * @see #child
228 * @since 13810 (signature)
229 */
230 public Environment withChild(IPrimitive child) {
231 Environment e = new Environment(this);
232 e.child = child;
233 return e;
234 }
235
236 /**
237 * Creates a clone of this environment, with the specified child, index, and context set to {@link Context#LINK}.
238 * @param child the matching child object
239 * @param index index of node in parent way or member in parent relation
240 * @param count count of nodes in parent way or members in parent relation
241 * @return A clone of this environment, with the specified child, index, and context set to {@code Context#LINK}
242 * @see #child
243 * @see #index
244 * @since 6175
245 * @since 13810 (signature)
246 */
247 public Environment withChildAndIndexAndLinkContext(IPrimitive child, int index, int count) {
248 Environment e = new Environment(this);
249 e.child = child;
250 e.index = index;
251 e.count = count;
252 e.context = Context.LINK;
253 return e;
254 }
255
256 /**
257 * Creates a clone of this environment, with the specified index.
258 * @param index index of node in parent way or member in parent relation
259 * @param count count of nodes in parent way or members in parent relation
260 * @return A clone of this environment, with the specified index
261 * @see #index
262 */
263 public Environment withIndex(int index, int count) {
264 Environment e = new Environment(this);
265 e.index = index;
266 e.count = count;
267 return e;
268 }
269
270 /**
271 * Creates a clone of this environment, with the specified {@link Context}.
272 * @param context context
273 * @return A clone of this environment, with the specified {@code Context}
274 */
275 public Environment withContext(Context context) {
276 Environment e = new Environment(this);
277 e.context = context == null ? Context.PRIMITIVE : context;
278 return e;
279 }
280
281 /**
282 * Creates a clone of this environment, with context set to {@link Context#LINK}.
283 * @return A clone of this environment, with context set to {@code Context#LINK}
284 */
285 public Environment withLinkContext() {
286 Environment e = new Environment(this);
287 e.context = Context.LINK;
288 return e;
289 }
290
291 /**
292 * Creates a clone of this environment, with the selector set
293 * @param selector The selector to use
294 * @return A clone of this environment, with the specified selector
295 * @since 18757
296 */
297 public Environment withSelector(Selector selector) {
298 return new Environment(this, selector);
299 }
300
301 /**
302 * Determines if the context of this environment is {@link Context#LINK}.
303 * @return {@code true} if the context of this environment is {@code Context#LINK}, {@code false} otherwise
304 */
305 public boolean isLinkContext() {
306 return Context.LINK == context;
307 }
308
309 /**
310 * Determines if this environment has a relation as parent.
311 * @return {@code true} if this environment has a relation as parent, {@code false} otherwise
312 * @see #parent
313 */
314 public boolean hasParentRelation() {
315 return parent instanceof Relation;
316 }
317
318 /**
319 * Replies the current context.
320 *
321 * @return the current context
322 */
323 public Context getContext() {
324 return context == null ? Context.PRIMITIVE : context;
325 }
326
327 /**
328 * Gets the role of the matching primitive in the relation
329 * @return The role
330 */
331 public String getRole() {
332 if (getContext() == Context.PRIMITIVE)
333 return null;
334
335 if (parent instanceof Relation)
336 return ((Relation) parent).getMember(index).getRole();
337 if (child != null && osm instanceof Relation)
338 return ((Relation) osm).getMember(index).getRole();
339 return null;
340 }
341
342 /**
343 * Get the selector for this environment
344 * @return The selector. May be {@code null}.
345 * @since 18757
346 */
347 public Selector selector() {
348 return this.selector;
349 }
350
351 /**
352 * Clears all matching context information
353 * @return this
354 */
355 public Environment clearSelectorMatchingInformation() {
356 parent = null;
357 child = null;
358 index = null;
359 count = null;
360 children = null;
361 intersections = null;
362 crossingWaysMap = null;
363 return this;
364 }
365
366 /**
367 * Gets the current cascade for the current layer of this environment
368 * @return The cascade
369 */
370 public Cascade getCascade() {
371 return getCascade(null);
372 }
373
374 /**
375 * Gets the current cascade for a given layer
376 * @param layer The layer to use, <code>null</code> to use the layer of the {@link Environment}
377 * @return The cascade
378 */
379 public Cascade getCascade(String layer) {
380 return mc == null ? null : mc.getCascade(layer == null ? this.layer : layer);
381 }
382}
Note: See TracBrowser for help on using the repository browser.