source: josm/trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/ComputeStyleListWorker.java@ 11971

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

javadoc

  • Property svn:eol-style set to native
File size: 6.9 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.osm.visitor.paint;
3
4import java.util.ArrayList;
5import java.util.Collection;
6import java.util.List;
7import java.util.concurrent.ForkJoinTask;
8import java.util.concurrent.RecursiveTask;
9
10import org.openstreetmap.josm.Main;
11import org.openstreetmap.josm.data.osm.Changeset;
12import org.openstreetmap.josm.data.osm.Node;
13import org.openstreetmap.josm.data.osm.OsmPrimitive;
14import org.openstreetmap.josm.data.osm.Relation;
15import org.openstreetmap.josm.data.osm.Way;
16import org.openstreetmap.josm.data.osm.visitor.Visitor;
17import org.openstreetmap.josm.data.osm.visitor.paint.StyledMapRenderer.StyleRecord;
18import org.openstreetmap.josm.gui.NavigatableComponent;
19import org.openstreetmap.josm.gui.mappaint.ElemStyles;
20import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
21import org.openstreetmap.josm.gui.mappaint.StyleElementList;
22import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSStyleSource;
23import org.openstreetmap.josm.gui.mappaint.styleelement.AreaElement;
24import org.openstreetmap.josm.gui.mappaint.styleelement.AreaIconElement;
25import org.openstreetmap.josm.gui.mappaint.styleelement.NodeElement;
26import org.openstreetmap.josm.gui.mappaint.styleelement.StyleElement;
27import org.openstreetmap.josm.gui.mappaint.styleelement.TextElement;
28import org.openstreetmap.josm.tools.JosmRuntimeException;
29import org.openstreetmap.josm.tools.bugreport.BugReport;
30
31/**
32 * Helper to compute style list.
33 * @since 11914 (extracted from StyledMapRenderer)
34 */
35public class ComputeStyleListWorker extends RecursiveTask<List<StyleRecord>> implements Visitor {
36 private final transient List<? extends OsmPrimitive> input;
37 private final transient List<StyleRecord> output;
38
39 private final transient ElemStyles styles = MapPaintStyles.getStyles();
40 private final int directExecutionTaskSize;
41 private final double circum;
42 private final NavigatableComponent nc;
43
44 private final boolean drawArea;
45 private final boolean drawMultipolygon;
46 private final boolean drawRestriction;
47
48 /**
49 * Constructs a new {@code ComputeStyleListWorker}.
50 * @param circum distance on the map in meters that 100 screen pixels represent
51 * @param nc navigatable component
52 * @param input the primitives to process
53 * @param output the list of styles to which styles will be added
54 * @param directExecutionTaskSize the threshold deciding whether to subdivide the tasks
55 */
56 ComputeStyleListWorker(double circum, NavigatableComponent nc,
57 final List<? extends OsmPrimitive> input, List<StyleRecord> output, int directExecutionTaskSize) {
58 this.circum = circum;
59 this.nc = nc;
60 this.input = input;
61 this.output = output;
62 this.directExecutionTaskSize = directExecutionTaskSize;
63 this.drawArea = circum <= Main.pref.getInteger("mappaint.fillareas", 10_000_000);
64 this.drawMultipolygon = drawArea && Main.pref.getBoolean("mappaint.multipolygon", true);
65 this.drawRestriction = Main.pref.getBoolean("mappaint.restriction", true);
66 this.styles.setDrawMultipolygon(drawMultipolygon);
67 }
68
69 @Override
70 protected List<StyleRecord> compute() {
71 if (input.size() <= directExecutionTaskSize) {
72 return computeDirectly();
73 } else {
74 final Collection<ForkJoinTask<List<StyleRecord>>> tasks = new ArrayList<>();
75 for (int fromIndex = 0; fromIndex < input.size(); fromIndex += directExecutionTaskSize) {
76 final int toIndex = Math.min(fromIndex + directExecutionTaskSize, input.size());
77 tasks.add(new ComputeStyleListWorker(circum, nc, input.subList(fromIndex, toIndex),
78 new ArrayList<>(directExecutionTaskSize), directExecutionTaskSize).fork());
79 }
80 for (ForkJoinTask<List<StyleRecord>> task : tasks) {
81 output.addAll(task.join());
82 }
83 return output;
84 }
85 }
86
87 /**
88 * Compute directly (without using fork/join) the style list. Only called for small input.
89 * @return list of computed style records
90 */
91 public List<StyleRecord> computeDirectly() {
92 MapCSSStyleSource.STYLE_SOURCE_LOCK.readLock().lock();
93 try {
94 for (final OsmPrimitive osm : input) {
95 acceptDrawable(osm);
96 }
97 return output;
98 } catch (JosmRuntimeException | IllegalArgumentException | IllegalStateException e) {
99 throw BugReport.intercept(e).put("input-size", input.size()).put("output-size", output.size());
100 } finally {
101 MapCSSStyleSource.STYLE_SOURCE_LOCK.readLock().unlock();
102 }
103 }
104
105 private void acceptDrawable(final OsmPrimitive osm) {
106 try {
107 if (osm.isDrawable()) {
108 osm.accept(this);
109 }
110 } catch (JosmRuntimeException | IllegalArgumentException | IllegalStateException e) {
111 throw BugReport.intercept(e).put("osm", osm);
112 }
113 }
114
115 @Override
116 public void visit(Node n) {
117 add(n, StyledMapRenderer.computeFlags(n, false));
118 }
119
120 @Override
121 public void visit(Way w) {
122 add(w, StyledMapRenderer.computeFlags(w, true));
123 }
124
125 @Override
126 public void visit(Relation r) {
127 add(r, StyledMapRenderer.computeFlags(r, true));
128 }
129
130 @Override
131 public void visit(Changeset cs) {
132 throw new UnsupportedOperationException();
133 }
134
135 /**
136 * Add new style records for the given node.
137 * @param osm node
138 * @param flags flags
139 */
140 public void add(Node osm, int flags) {
141 StyleElementList sl = styles.get(osm, circum, nc);
142 for (StyleElement s : sl) {
143 output.add(new StyleRecord(s, osm, flags));
144 }
145 }
146
147 /**
148 * Add new style records for the given way.
149 * @param osm way
150 * @param flags flags
151 */
152 public void add(Way osm, int flags) {
153 StyleElementList sl = styles.get(osm, circum, nc);
154 for (StyleElement s : sl) {
155 if ((drawArea && (flags & StyledMapRenderer.FLAG_DISABLED) == 0) || !(s instanceof AreaElement)) {
156 output.add(new StyleRecord(s, osm, flags));
157 }
158 }
159 }
160
161 /**
162 * Add new style records for the given relation.
163 * @param osm relation
164 * @param flags flags
165 */
166 public void add(Relation osm, int flags) {
167 StyleElementList sl = styles.get(osm, circum, nc);
168 for (StyleElement s : sl) {
169 if (drawAreaElement(flags, s) ||
170 (drawMultipolygon && drawArea && s instanceof TextElement) ||
171 (drawRestriction && s instanceof NodeElement)) {
172 output.add(new StyleRecord(s, osm, flags));
173 }
174 }
175 }
176
177 private boolean drawAreaElement(int flags, StyleElement s) {
178 return drawMultipolygon && drawArea && (s instanceof AreaElement || s instanceof AreaIconElement)
179 && (flags & StyledMapRenderer.FLAG_DISABLED) == 0;
180 }
181}
Note: See TracBrowser for help on using the repository browser.