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

Last change on this file since 15991 was 15959, checked in by GerdP, 6 years ago

fix #13165 Validator did not warn about overlapping multipolygons

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