source: josm/trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPaintVisitor.java@ 4005

Last change on this file since 4005 was 4005, checked in by bastiK, 13 years ago

mapcss: MapPaintVisitor rework (more flexibility with z-index)

  • Property svn:eol-style set to native
File size: 8.0 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.data.osm.visitor.paint;
3
4import java.awt.Graphics2D;
5import java.awt.RenderingHints;
6import java.util.ArrayList;
7import java.util.Collections;
8import java.util.Comparator;
9import java.util.List;
10
11import org.openstreetmap.josm.Main;
12import org.openstreetmap.josm.data.Bounds;
13import org.openstreetmap.josm.data.osm.BBox;
14import org.openstreetmap.josm.data.osm.DataSet;
15import org.openstreetmap.josm.data.osm.Node;
16import org.openstreetmap.josm.data.osm.OsmPrimitive;
17import org.openstreetmap.josm.data.osm.Relation;
18import org.openstreetmap.josm.data.osm.Way;
19import org.openstreetmap.josm.gui.NavigatableComponent;
20import org.openstreetmap.josm.gui.mappaint.AreaElemStyle;
21import org.openstreetmap.josm.gui.mappaint.ElemStyle;
22import org.openstreetmap.josm.gui.mappaint.ElemStyles;
23import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
24import org.openstreetmap.josm.gui.mappaint.NodeElemStyle;
25import org.openstreetmap.josm.gui.mappaint.StyleCache.StyleList;
26import org.openstreetmap.josm.tools.Pair;
27
28public class MapPaintVisitor implements PaintVisitor {
29
30 private Graphics2D g;
31 private boolean inactive;
32 private NavigatableComponent nc;
33
34 private ElemStyles styles;
35 private double circum;
36 private MapPainter painter;
37 private MapPaintSettings paintSettings;
38 private DataSet data;
39
40 private class StyleCollector {
41 private final boolean drawArea;
42 private final boolean drawMultipolygon;
43 private final boolean drawRestriction;
44 private final boolean memberSelected;
45
46 private final List<Pair<ElemStyle, OsmPrimitive>> styleElems;
47
48 public StyleCollector(boolean drawArea, boolean drawMultipolygon, boolean drawRestriction, boolean memberSelected) {
49 this.drawArea = drawArea;
50 this.drawMultipolygon = drawMultipolygon;
51 this.drawRestriction = drawRestriction;
52 this.memberSelected = memberSelected;
53 styleElems = new ArrayList<Pair<ElemStyle, OsmPrimitive>>();
54 }
55
56 public void add(Node osm) {
57 StyleList sl = styles.get(osm, circum, nc);
58 for (ElemStyle s : sl) {
59 styleElems.add(new Pair<ElemStyle, OsmPrimitive>(s, osm));
60 }
61 }
62
63 public void add(Way osm) {
64 StyleList sl = styles.get(osm, circum, nc);
65 for (ElemStyle s : sl) {
66 if (!drawArea && s instanceof AreaElemStyle) {
67 continue;
68 }
69 styleElems.add(new Pair<ElemStyle, OsmPrimitive>(s, osm));
70 }
71 }
72
73 public void add(Relation osm) {
74 StyleList sl = styles.get(osm, circum, nc);
75 for (ElemStyle s : sl) {
76 if (drawMultipolygon && drawArea && s instanceof AreaElemStyle) {
77 styleElems.add(new Pair<ElemStyle, OsmPrimitive>(s, osm));
78 } else if (drawRestriction && s instanceof NodeElemStyle) {
79 styleElems.add(new Pair<ElemStyle, OsmPrimitive>(s, osm));
80 }
81 }
82 }
83
84 public void drawAll() {
85 Collections.sort(styleElems, STYLE_COMPARATOR);
86 for (Pair<ElemStyle, OsmPrimitive> p : styleElems) {
87 p.a.paintPrimitive(p.b, paintSettings, painter, data.isSelected(p.b), memberSelected);
88 }
89 }
90 }
91
92 private final static Comparator<Pair<ElemStyle, OsmPrimitive>> STYLE_COMPARATOR = new Comparator<Pair<ElemStyle, OsmPrimitive>>() {
93 @Override
94 public int compare(Pair<ElemStyle, OsmPrimitive> p1, Pair<ElemStyle, OsmPrimitive> p2) {
95 int d1 = Float.compare(p1.a.z_index, p2.a.z_index);
96 if (d1 != 0)
97 return d1;
98 if (p1.a == NodeElemStyle.SIMPLE_NODE_ELEMSTYLE && p2.a != NodeElemStyle.SIMPLE_NODE_ELEMSTYLE)
99 return 1;
100 if (p1.a != NodeElemStyle.SIMPLE_NODE_ELEMSTYLE && p2.a == NodeElemStyle.SIMPLE_NODE_ELEMSTYLE)
101 return -1;
102 // newer primitives to the front
103 long id = p1.b.getUniqueId() - p2.b.getUniqueId();
104 if (id > 0)
105 return 1;
106 if (id < 0)
107 return -1;
108 return Float.compare(p1.a.object_z_index, p2.a.object_z_index);
109 }
110 };
111
112 public void visitAll(final DataSet data, boolean virtual, Bounds bounds) {
113 //long start = System.currentTimeMillis();
114 BBox bbox = new BBox(bounds);
115 this.data = data;
116
117 styles = MapPaintStyles.getStyles();
118
119 this.paintSettings = MapPaintSettings.INSTANCE;
120
121 circum = nc.getDist100Pixel();
122 boolean drawArea = circum <= Main.pref.getInteger("mappaint.fillareas", 10000000);
123 boolean drawMultipolygon = drawArea && Main.pref.getBoolean("mappaint.multipolygon", true);
124 styles.setDrawMultipolygon(drawMultipolygon);
125 boolean drawRestriction = Main.pref.getBoolean("mappaint.restriction", true);
126 boolean leftHandTraffic = Main.pref.getBoolean("mappaint.lefthandtraffic", false);
127
128 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
129 Main.pref.getBoolean("mappaint.use-antialiasing", true) ?
130 RenderingHints.VALUE_ANTIALIAS_ON : RenderingHints.VALUE_ANTIALIAS_OFF);
131
132 this.painter = new MapPainter(paintSettings, g, inactive, nc, virtual, circum, leftHandTraffic);
133
134 StyleCollector scDisabledPrimitives = new StyleCollector(false, false, drawRestriction, false);
135 StyleCollector scSelectedPrimitives = new StyleCollector(drawArea, drawMultipolygon, drawRestriction, false);
136 StyleCollector scMemberPrimitives = new StyleCollector(drawArea, drawMultipolygon, drawRestriction, true);
137 StyleCollector scNormalPrimitives = new StyleCollector(drawArea, drawMultipolygon, drawRestriction, false);
138
139 for (final Node n: data.searchNodes(bbox)) {
140 if (n.isDrawable()) {
141 if (n.isDisabled()) {
142 scDisabledPrimitives.add(n);
143 } else if (n.isSelected()) {
144 scSelectedPrimitives.add(n);
145 } else if (n.isMemberOfSelected()) {
146 scMemberPrimitives.add(n);
147 } else {
148 scNormalPrimitives.add(n);
149 }
150 }
151 }
152 for (final Way w : data.searchWays(bbox)) {
153 if (w.isDrawable()) {
154 if (w.isDisabled()) {
155 scDisabledPrimitives.add(w);
156 } else if (w.isSelected()) {
157 scSelectedPrimitives.add(w);
158 } else if (w.isMemberOfSelected()) {
159 scMemberPrimitives.add(w);
160 } else {
161 scNormalPrimitives.add(w);
162 }
163 }
164 }
165 for (Relation r: data.searchRelations(bbox)) {
166 if (r.isDrawable()) {
167 if (r.isDisabled()) {
168 scDisabledPrimitives.add(r);
169 } else if (r.isSelected()) {
170 scSelectedPrimitives.add(r);
171 } else {
172 scNormalPrimitives.add(r);
173 }
174 }
175 }
176
177 //long phase1 = System.currentTimeMillis();
178
179 scDisabledPrimitives.drawAll();
180 scDisabledPrimitives = null;
181 scNormalPrimitives.drawAll();
182 scNormalPrimitives = null;
183 scMemberPrimitives.drawAll();
184 scMemberPrimitives = null;
185 scSelectedPrimitives.drawAll();
186 scSelectedPrimitives = null;
187
188 painter.drawVirtualNodes(data.searchWays(bbox));
189
190 //long now = System.currentTimeMillis();
191 //System.err.println(String.format("PAINTING TOOK %d [PHASE1 took %d] (at scale %s)", now - start, phase1 - start, circum));
192 }
193
194 public void setGraphics(Graphics2D g) {
195 this.g = g;
196 }
197
198 public void setInactive(boolean inactive) {
199 this.inactive = inactive;
200 }
201
202 public void setNavigatableComponent(NavigatableComponent nc) {
203 this.nc = nc;
204 }
205}
Note: See TracBrowser for help on using the repository browser.