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

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

replace abstract class AbstractVisitor by interface OsmPrimitiveVisitor; deprecate Visitor

  • data.osm.visitor.Visitor awkwardly mixes OsmPrimitive types and Changeset class; this may have been used in the past, but is no longer needed; AbstractVisitor should have been a super-interface of Visitor in the first place
  • hopefully, this is binary compatible and plugins can be updated gracefully
  • 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.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.OsmPrimitiveVisitor;
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 OsmPrimitiveVisitor {
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 /**
131 * Add new style records for the given node.
132 * @param osm node
133 * @param flags flags
134 */
135 public void add(Node osm, int flags) {
136 StyleElementList sl = styles.get(osm, circum, nc);
137 for (StyleElement s : sl) {
138 output.add(new StyleRecord(s, osm, flags));
139 }
140 }
141
142 /**
143 * Add new style records for the given way.
144 * @param osm way
145 * @param flags flags
146 */
147 public void add(Way osm, int flags) {
148 StyleElementList sl = styles.get(osm, circum, nc);
149 for (StyleElement s : sl) {
150 if ((drawArea && (flags & StyledMapRenderer.FLAG_DISABLED) == 0) || !(s instanceof AreaElement)) {
151 output.add(new StyleRecord(s, osm, flags));
152 }
153 }
154 }
155
156 /**
157 * Add new style records for the given relation.
158 * @param osm relation
159 * @param flags flags
160 */
161 public void add(Relation osm, int flags) {
162 StyleElementList sl = styles.get(osm, circum, nc);
163 for (StyleElement s : sl) {
164 if (drawAreaElement(flags, s) ||
165 (drawMultipolygon && drawArea && s instanceof TextElement) ||
166 (drawRestriction && s instanceof NodeElement)) {
167 output.add(new StyleRecord(s, osm, flags));
168 }
169 }
170 }
171
172 private boolean drawAreaElement(int flags, StyleElement s) {
173 return drawMultipolygon && drawArea && (s instanceof AreaElement || s instanceof AreaIconElement)
174 && (flags & StyledMapRenderer.FLAG_DISABLED) == 0;
175 }
176}
Note: See TracBrowser for help on using the repository browser.