Ticket #5641: patch.diff

File patch.diff, 20.8 KB (added by Don-vip, 7 years ago)
  • src/org/openstreetmap/josm/data/osm/visitor/paint/RenderBenchmarkCollector.java

     
    1818 * @since 10697
    1919 */
    2020public 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
    2142    /**
    2243     * Notified when the renderer method starts preparing the data
    2344     * @param circum The current circum of the view.
     
    115136     * A special version of the benchmark class that logs the output to stderr.
    116137     * @author Michael Zangl
    117138     */
    118     public static class LoggingBenchmark extends RenderBenchmarkCollector.CapturingBenchmark {
     139    public static class LoggingBenchmark extends CapturingBenchmark {
    119140        private final PrintStream outStream = System.err;
    120141        private double circum;
    121142
     
    123144        public void renderStart(double circum) {
    124145            this.circum = circum;
    125146            super.renderStart(circum);
    126             outStream.print("BENCHMARK: rendering ");
     147            outStream.print("BENCHMARK " + name + ": rendering ");
    127148        }
    128149
    129150        @Override
  • src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java

     
    11771177                                (p, gv) -> p.append(gv.getOutline(0, 0), false),
    11781178                                (p1, p2) -> p1.append(p2, false)),
    11791179                        osm.isDisabled(), text);
    1180             } else {
    1181                 Logging.trace("Couldn't find a correct label placement for {0} / {1}", osm, name);
    11821180            }
    11831181        });
    11841182        g.setFont(defaultFont);
     
    16351633    @Override
    16361634    public void render(final OsmData<?, ?, ?, ?> data, boolean renderVirtualNodes, Bounds bounds) {
    16371635        RenderBenchmarkCollector benchmark = benchmarkFactory.get();
     1636        benchmark.setName(data.getName());
    16381637        BBox bbox = bounds.toBBox();
    16391638        getSettings(renderVirtualNodes);
    16401639
  • src/org/openstreetmap/josm/gui/draw/CompositeStroke.java

     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.gui.draw;
     3
     4import java.awt.Shape;
     5import java.awt.Stroke;
     6import java.util.Objects;
     7
     8/**
     9 * A composite stroke draws the outline of the stroke using another stroke.
     10 * @since xxx
     11 */
     12public 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
     
    1515import org.openstreetmap.josm.actions.RenameLayerAction;
    1616import org.openstreetmap.josm.actions.SaveActionBase;
    1717import org.openstreetmap.josm.data.Bounds;
     18import org.openstreetmap.josm.data.osm.DataSet;
    1819import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
     20import org.openstreetmap.josm.data.osm.visitor.paint.RenderBenchmarkCollector;
    1921import org.openstreetmap.josm.data.validation.OsmValidator;
    2022import org.openstreetmap.josm.data.validation.Severity;
    2123import org.openstreetmap.josm.data.validation.TestError;
     
    3133import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
    3234import org.openstreetmap.josm.gui.layer.validation.PaintVisitor;
    3335import org.openstreetmap.josm.tools.ImageProvider;
     36import org.openstreetmap.josm.tools.Logging;
    3437import org.openstreetmap.josm.tools.MultiMap;
    3538
    3639/**
     
    6972    @Override
    7073    public void paint(final Graphics2D g, final MapView mv, Bounds bounds) {
    7174        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)
    7377            return;
    7478
    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();
    7683
     84        PaintVisitor paintVisitor = new PaintVisitor(g, mv, data, bounds);
     85
     86        benchmark.renderDraw(null);
    7787        DefaultMutableTreeNode severity = (DefaultMutableTreeNode) root.getLastChild();
    7888        while (severity != null) {
     89            Logging.debug("Paiting " + severity);
    7990            ValidatorTreePanel.visitTestErrors(severity, paintVisitor::visit);
    8091
    8192            // Severities in inverse order
     
    8394        }
    8495
    8596        paintVisitor.clearPaintedObjects();
     97        benchmark.renderDone();
    8698    }
    8799
    88100    @Override
  • src/org/openstreetmap/josm/gui/layer/validation/PaintVisitor.java

     
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.gui.layer.validation;
    33
     4import java.awt.BasicStroke;
    45import java.awt.Color;
    56import java.awt.Graphics2D;
    6 import java.awt.Point;
     7import java.awt.Shape;
     8import java.awt.Stroke;
     9import java.awt.geom.Point2D;
     10import java.util.Arrays;
     11import java.util.HashMap;
    712import java.util.HashSet;
    813import java.util.List;
     14import java.util.Map;
    915import java.util.Objects;
    1016import java.util.Set;
     17import java.util.stream.Collectors;
    1118
    12 import org.openstreetmap.josm.data.coor.LatLon;
     19import org.openstreetmap.josm.data.Bounds;
     20import org.openstreetmap.josm.data.osm.DataSet;
    1321import org.openstreetmap.josm.data.osm.Node;
    1422import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1523import org.openstreetmap.josm.data.osm.Relation;
     
    1927import org.openstreetmap.josm.data.validation.TestError;
    2028import org.openstreetmap.josm.data.validation.ValidatorVisitor;
    2129import org.openstreetmap.josm.gui.MapView;
     30import org.openstreetmap.josm.gui.draw.CompositeStroke;
    2231import org.openstreetmap.josm.gui.draw.MapViewPath;
    2332import org.openstreetmap.josm.gui.draw.SymbolShape;
     33import org.openstreetmap.josm.tools.Logging;
    2434import org.openstreetmap.josm.tools.Utils;
    2535
    2636/**
     
    4252
    4353    private final Set<PaintedPoint> paintedPoints = new HashSet<>();
    4454    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));
    4567
    4668    /**
    4769     * Constructor
    4870     * @param g The graphics
    4971     * @param mv The Mapview
     72     * @param data dataset to render
     73     * @param bounds bounds to render
    5074     */
    51     public PaintVisitor(Graphics2D g, MapView mv) {
     75    public PaintVisitor(Graphics2D g, MapView mv, DataSet data, Bounds bounds) {
    5276        this.g = g;
    5377        this.mv = mv;
     78        this.nodes = data.searchNodes(bounds.toBBox()).parallelStream().map(Node::getUniqueId).collect(Collectors.toSet());
    5479    }
    5580
    5681    protected static class PaintedPoint {
    57         protected final LatLon p1;
     82        protected final double lat1;
     83        protected final double lon1;
    5884        protected final Color color;
    5985
    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;
    6289            this.color = color;
    6390        }
    6491
    6592        @Override
    6693        public int hashCode() {
    67             return Objects.hash(p1, color);
     94            return Objects.hash(color, lat1, lon1);
    6895        }
    6996
    7097        @Override
    7198        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);
    77107        }
    78108    }
    79109
    80110    protected static class PaintedSegment extends PaintedPoint {
    81         private final LatLon p2;
     111        private final double lat2;
     112        private final double lon2;
    82113
    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;
    86118        }
    87119
    88120        @Override
    89121        public int hashCode() {
    90             return Objects.hash(super.hashCode(), p2);
     122            return Objects.hash(color, lat1, lon1, lat2, lon2);
    91123        }
    92124
    93125        @Override
    94126        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);
    100134        }
    101135    }
    102136
     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
    103162    @Override
    104163    public void visit(TestError error) {
    105164        if (error != null && !error.isIgnored()) {
     
    122181     * @param color The circle color
    123182     */
    124183    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)) {
    128186            MapViewPath circle = new MapViewPath(mv.getState()).shapeAround(n, SymbolShape.CIRCLE, 10);
    129187
    130188            if (selected) {
     
    133191            }
    134192            g.setColor(color);
    135193            g.draw(circle);
    136             paintedPoints.add(pp);
    137194        }
    138195    }
    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*/
    140210    /**
    141211     * Draws a line around the segment
    142212     *
     
    144214     * @param p2 The second point of segment
    145215     * @param color The color
    146216     */
    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();
    148219
    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());
    150221        double cosT = 5 * Math.cos(t);
    151222        double sinT = 5 * Math.sin(t);
    152223        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)};
    153228        if (selected) {
    154229            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)};
    159230            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);
    162233        }
    163234        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        }
    170251    }
    171252
    172253    /**
     
    177258     * @param color The color
    178259     */
    179260    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);
    185275            }
     276            //drawSegment(mv.getPoint2D(n1), mv.getPoint2D(n2), color);
    186277        }
    187278    }
    188279
     
    201292
    202293    @Override
    203294    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        }
    205301    }
    206302
    207303    @Override
     
    222318     * @return true if the node is visible
    223319     */
    224320    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());
    227322    }
    228323
    229324    /**
     
    234329     * @return {@code true} if the segment is visible
    235330     */
    236331    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);
    243339    }
    244340
    245341    @Override
    246342    public void visit(List<Node> nodes) {
    247343        Node lastN = null;
    248344        for (Node n : nodes) {
    249             if (lastN == null) {
    250                 lastN = n;
    251                 continue;
     345            if (lastN != null) {
     346                drawSegment(lastN, n, color);
    252347            }
    253             drawSegment(lastN, n, color);
    254348            lastN = n;
    255349        }
    256350    }
     
    261355     * @return The color.
    262356     */
    263357    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)));
    265359    }
    266360
    267361    /**
     
    270364    public void clearPaintedObjects() {
    271365        paintedPoints.clear();
    272366        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        }
    273373    }
    274374}