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

Last change on this file since 12813 was 12813, checked in by bastiK, 7 years ago

fix PMD, etc.

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