Ticket #5641: patch.diff
| File patch.diff, 20.8 KB (added by , 7 years ago) |
|---|
-
src/org/openstreetmap/josm/data/osm/visitor/paint/RenderBenchmarkCollector.java
18 18 * @since 10697 19 19 */ 20 20 public class RenderBenchmarkCollector { 21 22 protected String name = ""; 23 24 /** 25 * Returns this collector name. 26 * @return this collector name 27 * @since xxx 28 */ 29 public String getName() { 30 return name; 31 } 32 33 /** 34 * Sets this collector name. 35 * @param name this collector name 36 * @since xxx 37 */ 38 public void setName(String name) { 39 this.name = name; 40 } 41 21 42 /** 22 43 * Notified when the renderer method starts preparing the data 23 44 * @param circum The current circum of the view. … … 115 136 * A special version of the benchmark class that logs the output to stderr. 116 137 * @author Michael Zangl 117 138 */ 118 public static class LoggingBenchmark extends RenderBenchmarkCollector.CapturingBenchmark {139 public static class LoggingBenchmark extends CapturingBenchmark { 119 140 private final PrintStream outStream = System.err; 120 141 private double circum; 121 142 … … 123 144 public void renderStart(double circum) { 124 145 this.circum = circum; 125 146 super.renderStart(circum); 126 outStream.print("BENCHMARK : rendering ");147 outStream.print("BENCHMARK " + name + ": rendering "); 127 148 } 128 149 129 150 @Override -
src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java
1177 1177 (p, gv) -> p.append(gv.getOutline(0, 0), false), 1178 1178 (p1, p2) -> p1.append(p2, false)), 1179 1179 osm.isDisabled(), text); 1180 } else {1181 Logging.trace("Couldn't find a correct label placement for {0} / {1}", osm, name);1182 1180 } 1183 1181 }); 1184 1182 g.setFont(defaultFont); … … 1635 1633 @Override 1636 1634 public void render(final OsmData<?, ?, ?, ?> data, boolean renderVirtualNodes, Bounds bounds) { 1637 1635 RenderBenchmarkCollector benchmark = benchmarkFactory.get(); 1636 benchmark.setName(data.getName()); 1638 1637 BBox bbox = bounds.toBBox(); 1639 1638 getSettings(renderVirtualNodes); 1640 1639 -
src/org/openstreetmap/josm/gui/draw/CompositeStroke.java
1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm.gui.draw; 3 4 import java.awt.Shape; 5 import java.awt.Stroke; 6 import java.util.Objects; 7 8 /** 9 * A composite stroke draws the outline of the stroke using another stroke. 10 * @since xxx 11 */ 12 public class CompositeStroke implements Stroke { 13 private final Stroke stroke1; 14 private final Stroke stroke2; 15 16 /** 17 * Constructs a new {@code CompositeStroke}. 18 * @param stroke1 stroke that strokes the shape to render 19 * @param stroke2 stroke that strokes the shape resulting of the first stroke 20 */ 21 public CompositeStroke(Stroke stroke1, Stroke stroke2) { 22 this.stroke1 = Objects.requireNonNull(stroke1); 23 this.stroke2 = Objects.requireNonNull(stroke2); 24 } 25 26 @Override 27 public Shape createStrokedShape(Shape shape) { 28 return stroke2.createStrokedShape(stroke1.createStrokedShape(shape)); 29 } 30 } -
src/org/openstreetmap/josm/gui/layer/ValidatorLayer.java
Property changes on: src\org\openstreetmap\josm\gui\draw\CompositeStroke.java ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native
15 15 import org.openstreetmap.josm.actions.RenameLayerAction; 16 16 import org.openstreetmap.josm.actions.SaveActionBase; 17 17 import org.openstreetmap.josm.data.Bounds; 18 import org.openstreetmap.josm.data.osm.DataSet; 18 19 import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor; 20 import org.openstreetmap.josm.data.osm.visitor.paint.RenderBenchmarkCollector; 19 21 import org.openstreetmap.josm.data.validation.OsmValidator; 20 22 import org.openstreetmap.josm.data.validation.Severity; 21 23 import org.openstreetmap.josm.data.validation.TestError; … … 31 33 import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent; 32 34 import org.openstreetmap.josm.gui.layer.validation.PaintVisitor; 33 35 import org.openstreetmap.josm.tools.ImageProvider; 36 import org.openstreetmap.josm.tools.Logging; 34 37 import org.openstreetmap.josm.tools.MultiMap; 35 38 36 39 /** … … 69 72 @Override 70 73 public void paint(final Graphics2D g, final MapView mv, Bounds bounds) { 71 74 DefaultMutableTreeNode root = MainApplication.getMap().validatorDialog.tree.getRoot(); 72 if (root == null || root.getChildCount() == 0) 75 DataSet data = MainApplication.getLayerManager().getActiveDataSet(); 76 if (root == null || root.getChildCount() == 0 || data == null) 73 77 return; 74 78 75 PaintVisitor paintVisitor = new PaintVisitor(g, mv); 79 RenderBenchmarkCollector benchmark = RenderBenchmarkCollector.defaultBenchmarkSupplier().get(); 80 benchmark.setName(getName()); 81 benchmark.renderStart(mv.getDist100Pixel()); 82 benchmark.renderSort(); 76 83 84 PaintVisitor paintVisitor = new PaintVisitor(g, mv, data, bounds); 85 86 benchmark.renderDraw(null); 77 87 DefaultMutableTreeNode severity = (DefaultMutableTreeNode) root.getLastChild(); 78 88 while (severity != null) { 89 Logging.debug("Paiting " + severity); 79 90 ValidatorTreePanel.visitTestErrors(severity, paintVisitor::visit); 80 91 81 92 // Severities in inverse order … … 83 94 } 84 95 85 96 paintVisitor.clearPaintedObjects(); 97 benchmark.renderDone(); 86 98 } 87 99 88 100 @Override -
src/org/openstreetmap/josm/gui/layer/validation/PaintVisitor.java
1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.gui.layer.validation; 3 3 4 import java.awt.BasicStroke; 4 5 import java.awt.Color; 5 6 import java.awt.Graphics2D; 6 import java.awt.Point; 7 import java.awt.Shape; 8 import java.awt.Stroke; 9 import java.awt.geom.Point2D; 10 import java.util.Arrays; 11 import java.util.HashMap; 7 12 import java.util.HashSet; 8 13 import java.util.List; 14 import java.util.Map; 9 15 import java.util.Objects; 10 16 import java.util.Set; 17 import java.util.stream.Collectors; 11 18 12 import org.openstreetmap.josm.data.coor.LatLon; 19 import org.openstreetmap.josm.data.Bounds; 20 import org.openstreetmap.josm.data.osm.DataSet; 13 21 import org.openstreetmap.josm.data.osm.Node; 14 22 import org.openstreetmap.josm.data.osm.OsmPrimitive; 15 23 import org.openstreetmap.josm.data.osm.Relation; … … 19 27 import org.openstreetmap.josm.data.validation.TestError; 20 28 import org.openstreetmap.josm.data.validation.ValidatorVisitor; 21 29 import org.openstreetmap.josm.gui.MapView; 30 import org.openstreetmap.josm.gui.draw.CompositeStroke; 22 31 import org.openstreetmap.josm.gui.draw.MapViewPath; 23 32 import org.openstreetmap.josm.gui.draw.SymbolShape; 33 import org.openstreetmap.josm.tools.Logging; 24 34 import org.openstreetmap.josm.tools.Utils; 25 35 26 36 /** … … 42 52 43 53 private final Set<PaintedPoint> paintedPoints = new HashSet<>(); 44 54 private final Set<PaintedSegment> paintedSegments = new HashSet<>(); 55 private final Set<PaintedWay> paintedWays = new HashSet<>(); 56 57 private final Set<Long> nodes; 58 private long drawSegmentTimeSpent; 59 private long drawArcTimeSpent; 60 private long drawLineTimeSpent; 61 62 private static final Map<Color, Color> highlightColors = new HashMap<>(); 63 64 private static final Stroke WAY_STROKE = new CompositeStroke( 65 new BasicStroke(10f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND), 66 new BasicStroke(1f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); 45 67 46 68 /** 47 69 * Constructor 48 70 * @param g The graphics 49 71 * @param mv The Mapview 72 * @param data dataset to render 73 * @param bounds bounds to render 50 74 */ 51 public PaintVisitor(Graphics2D g, MapView mv ) {75 public PaintVisitor(Graphics2D g, MapView mv, DataSet data, Bounds bounds) { 52 76 this.g = g; 53 77 this.mv = mv; 78 this.nodes = data.searchNodes(bounds.toBBox()).parallelStream().map(Node::getUniqueId).collect(Collectors.toSet()); 54 79 } 55 80 56 81 protected static class PaintedPoint { 57 protected final LatLon p1; 82 protected final double lat1; 83 protected final double lon1; 58 84 protected final Color color; 59 85 60 public PaintedPoint(LatLon p1, Color color) { 61 this.p1 = p1; 86 public PaintedPoint(double lat1, double lon1, Color color) { 87 this.lat1 = lat1; 88 this.lon1 = lon1; 62 89 this.color = color; 63 90 } 64 91 65 92 @Override 66 93 public int hashCode() { 67 return Objects.hash( p1, color);94 return Objects.hash(color, lat1, lon1); 68 95 } 69 96 70 97 @Override 71 98 public boolean equals(Object obj) { 72 if (this == obj) return true; 73 if (obj == null || getClass() != obj.getClass()) return false; 74 PaintedPoint that = (PaintedPoint) obj; 75 return Objects.equals(p1, that.p1) && 76 Objects.equals(color, that.color); 99 if (this == obj) 100 return true; 101 if (obj == null || getClass() != obj.getClass()) 102 return false; 103 PaintedPoint other = (PaintedPoint) obj; 104 return Objects.equals(color, other.color) 105 && Double.doubleToLongBits(lat1) == Double.doubleToLongBits(other.lat1) 106 && Double.doubleToLongBits(lon1) == Double.doubleToLongBits(other.lon1); 77 107 } 78 108 } 79 109 80 110 protected static class PaintedSegment extends PaintedPoint { 81 private final LatLon p2; 111 private final double lat2; 112 private final double lon2; 82 113 83 public PaintedSegment(LatLon p1, LatLon p2, Color color) { 84 super(p1, color); 85 this.p2 = p2; 114 public PaintedSegment(double lat1, double lon1, double lat2, double lon2, Color color) { 115 super(lat1, lon1, color); 116 this.lat2 = lat2; 117 this.lon2 = lon2; 86 118 } 87 119 88 120 @Override 89 121 public int hashCode() { 90 return Objects.hash( super.hashCode(), p2);122 return Objects.hash(color, lat1, lon1, lat2, lon2); 91 123 } 92 124 93 125 @Override 94 126 public boolean equals(Object obj) { 95 if (this == obj) return true; 96 if (obj == null || getClass() != obj.getClass()) return false; 97 if (!super.equals(obj)) return false; 98 PaintedSegment that = (PaintedSegment) obj; 99 return Objects.equals(p2, that.p2); 127 if (this == obj) 128 return true; 129 if (obj == null || getClass() != obj.getClass() || !super.equals(obj)) 130 return false; 131 PaintedSegment other = (PaintedSegment) obj; 132 return Double.doubleToLongBits(lat2) == Double.doubleToLongBits(other.lat2) 133 && Double.doubleToLongBits(lon2) == Double.doubleToLongBits(other.lon2); 100 134 } 101 135 } 102 136 137 protected static class PaintedWay { 138 private final Way w; 139 private final Color color; 140 141 public PaintedWay(Way w, Color color) { 142 this.w = w; 143 this.color = color; 144 } 145 146 @Override 147 public int hashCode() { 148 return Objects.hash(color, w); 149 } 150 151 @Override 152 public boolean equals(Object obj) { 153 if (this == obj) 154 return true; 155 if (obj == null || getClass() != obj.getClass()) 156 return false; 157 PaintedWay other = (PaintedWay) obj; 158 return Objects.equals(color, other.color) && Objects.equals(w, other.w); 159 } 160 } 161 103 162 @Override 104 163 public void visit(TestError error) { 105 164 if (error != null && !error.isIgnored()) { … … 122 181 * @param color The circle color 123 182 */ 124 183 protected void drawNode(Node n, Color color) { 125 PaintedPoint pp = new PaintedPoint(n.getCoor(), color); 126 127 if (!paintedPoints.contains(pp)) { 184 PaintedPoint pp = new PaintedPoint(n.lat(), n.lon(), color); 185 if (paintedPoints.add(pp)) { 128 186 MapViewPath circle = new MapViewPath(mv.getState()).shapeAround(n, SymbolShape.CIRCLE, 10); 129 187 130 188 if (selected) { … … 133 191 } 134 192 g.setColor(color); 135 193 g.draw(circle); 136 paintedPoints.add(pp);137 194 } 138 195 } 139 196 /* 197 protected void drawWay(Way w, Color color) { 198 PaintedWay pw = new PaintedWay(w, color); 199 if (paintedWays.add(pw)) { 200 MapViewPath path = new MapViewPath(mv.getState()); 201 if (w.isClosed()) { 202 path.appendClosed(w.getNodes(), false); 203 } else { 204 path.append(w.getNodes(), false); 205 } 206 g.draw(path.computeClippedLine(WAY_STROKE)); 207 } 208 } 209 */ 140 210 /** 141 211 * Draws a line around the segment 142 212 * … … 144 214 * @param p2 The second point of segment 145 215 * @param color The color 146 216 */ 147 protected void drawSegment(Point p1, Point p2, Color color) { 217 protected void drawSegment(Point2D p1, Point2D p2, Color color) { 218 long timeStart = System.currentTimeMillis(); 148 219 149 double t = Math.atan2( (double) p2.x - p1.x, (double) p2.y - p1.y);220 double t = Math.atan2(p2.getX() - p1.getX(), p2.getY() - p1.getY()); 150 221 double cosT = 5 * Math.cos(t); 151 222 double sinT = 5 * Math.sin(t); 152 223 int deg = (int) Utils.toDegrees(t); 224 int[] x = new int[] {(int) (p1.getX() + cosT), (int) (p2.getX() + cosT), 225 (int) (p2.getX() - cosT), (int) (p1.getX() - cosT)}; 226 int[] y = new int[] {(int) (p1.getY() - sinT), (int) (p2.getY() - sinT), 227 (int) (p2.getY() + sinT), (int) (p1.getY() + sinT)}; 153 228 if (selected) { 154 229 g.setColor(getHighlightColor(color)); 155 int[] x = new int[] {(int) (p1.x + cosT), (int) (p2.x + cosT),156 (int) (p2.x - cosT), (int) (p1.x - cosT)};157 int[] y = new int[] {(int) (p1.y - sinT), (int) (p2.y - sinT),158 (int) (p2.y + sinT), (int) (p1.y + sinT)};159 230 g.fillPolygon(x, y, 4); 160 g.fillArc( p1.x - 5, p1.y- 5, 10, 10, deg, 180);161 g.fillArc( p2.x - 5, p2.y- 5, 10, 10, deg, -180);231 g.fillArc((int) p1.getX() - 5, (int) p1.getY() - 5, 10, 10, deg, 180); 232 g.fillArc((int) p2.getX() - 5, (int) p2.getY() - 5, 10, 10, deg, -180); 162 233 } 163 234 g.setColor(color); 164 g.drawLine((int) (p1.x + cosT), (int) (p1.y - sinT), 165 (int) (p2.x + cosT), (int) (p2.y - sinT)); 166 g.drawLine((int) (p1.x - cosT), (int) (p1.y + sinT), 167 (int) (p2.x - cosT), (int) (p2.y + sinT)); 168 g.drawArc(p1.x - 5, p1.y - 5, 10, 10, deg, 180); 169 g.drawArc(p2.x - 5, p2.y - 5, 10, 10, deg, -180); 235 long timeLineStart = System.currentTimeMillis(); 236 g.drawLine(x[0], y[0], x[1], y[1]); 237 g.drawLine(x[3], y[3], x[2], y[2]); 238 if (Logging.isTraceEnabled()) { 239 drawLineTimeSpent += System.currentTimeMillis() - timeLineStart; 240 } 241 long timeArcStart = System.currentTimeMillis(); 242 g.drawArc((int) p1.getX() - 5, (int) p1.getY() - 5, 10, 10, deg, 180); 243 g.drawArc((int) p2.getX() - 5, (int) p2.getY() - 5, 10, 10, deg, -180); 244 if (Logging.isTraceEnabled()) { 245 drawArcTimeSpent += System.currentTimeMillis() - timeArcStart; 246 } 247 248 if (Logging.isTraceEnabled()) { 249 drawSegmentTimeSpent += System.currentTimeMillis() - timeStart; 250 } 170 251 } 171 252 172 253 /** … … 177 258 * @param color The color 178 259 */ 179 260 protected void drawSegment(Node n1, Node n2, Color color) { 180 if (n1.isDrawable() && n2.isDrawable() && isSegmentVisible(n1, n2)) { 181 PaintedSegment ps = new PaintedSegment(n1.getCoor(), n2.getCoor(), color); 182 if (!paintedSegments.contains(ps)) { 183 drawSegment(mv.getPoint(n1), mv.getPoint(n2), color); 184 paintedSegments.add(ps); 261 if (n1.isDrawable() && n2.isDrawable() && (isNodeVisible(n1) || isNodeVisible(n2) || isSegmentVisible(n1, n2)) 262 && paintedSegments.add(new PaintedSegment(n1.lat(), n1.lon(), n2.lat(), n2.lon(), color))) { 263 Shape shape = new MapViewPath(mv).append(Arrays.asList(n1, n2), false);//.computeClippedLine(WAY_STROKE); 264 Stroke oldStroke = g.getStroke(); 265 try { 266 g.setStroke(WAY_STROKE); 267 if (selected) { 268 g.setColor(getHighlightColor(color)); 269 g.fill(shape); 270 } 271 g.setColor(color); 272 g.draw(shape); 273 } finally { 274 g.setStroke(oldStroke); 185 275 } 276 //drawSegment(mv.getPoint2D(n1), mv.getPoint2D(n2), color); 186 277 } 187 278 } 188 279 … … 201 292 202 293 @Override 203 294 public void visit(Way w) { 204 visit(w.getNodes()); 295 /*if (w.isDrawable() && w.getNodes().parallelStream().anyMatch(this::isNodeVisible)) { 296 drawWay(w, color); 297 }*/ 298 if (w.isDrawable()) { 299 visit(w.getNodes()); 300 } 205 301 } 206 302 207 303 @Override … … 222 318 * @return true if the node is visible 223 319 */ 224 320 protected boolean isNodeVisible(Node n) { 225 Point p = mv.getPoint(n); 226 return !((p.x < 0) || (p.y < 0) || (p.x > mv.getWidth()) || (p.y > mv.getHeight())); 321 return nodes.contains(n.getUniqueId()); 227 322 } 228 323 229 324 /** … … 234 329 * @return {@code true} if the segment is visible 235 330 */ 236 331 protected boolean isSegmentVisible(Node n1, Node n2) { 237 Point p1 = mv.getPoint(n1); 238 Point p2 = mv.getPoint(n2); 239 return (p1.x >= 0 || p2.x >= 0) 240 && (p1.y >= 0 || p2.y >= 0) 241 && (p1.x <= mv.getWidth() || p2.x <= mv.getWidth()) 242 && (p1.y <= mv.getHeight() || p2.y <= mv.getHeight()); 332 Point2D p1 = mv.getPoint2D(n1); 333 Point2D p2 = mv.getPoint2D(n2); 334 return (p1.getX() >= 0 || p2.getX() >= 0) 335 && (p1.getY() >= 0 || p2.getY() >= 0) 336 && (p1.getX() <= mv.getWidth() || p2.getX() <= mv.getWidth()) 337 && (p1.getY() <= mv.getHeight() || p2.getY() <= mv.getHeight()); 338 //return isNodeVisible(n1) || isNodeVisible(n2); 243 339 } 244 340 245 341 @Override 246 342 public void visit(List<Node> nodes) { 247 343 Node lastN = null; 248 344 for (Node n : nodes) { 249 if (lastN == null) { 250 lastN = n; 251 continue; 345 if (lastN != null) { 346 drawSegment(lastN, n, color); 252 347 } 253 drawSegment(lastN, n, color);254 348 lastN = n; 255 349 } 256 350 } … … 261 355 * @return The color. 262 356 */ 263 357 private static Color getHighlightColor(Color color) { 264 return new Color(color.getRed(), color.getGreen(), color.getBlue(), (int) (color.getAlpha() * .4));358 return highlightColors.computeIfAbsent(color, c -> new Color(c.getRed(), c.getGreen(), c.getBlue(), (int) (c.getAlpha() * .4))); 265 359 } 266 360 267 361 /** … … 270 364 public void clearPaintedObjects() { 271 365 paintedPoints.clear(); 272 366 paintedSegments.clear(); 367 paintedWays.clear(); 368 if (Logging.isTraceEnabled()) { 369 Logging.trace("drawArcTimeSpent: {0}", Utils.getDurationString(drawArcTimeSpent)); 370 Logging.trace("drawLineTimeSpent: {0}", Utils.getDurationString(drawLineTimeSpent)); 371 Logging.trace("drawSegmentTimeSpent: {0}", Utils.getDurationString(drawSegmentTimeSpent)); 372 } 273 373 } 274 374 }
