Changeset 11026 in josm


Ignore:
Timestamp:
2016-09-19T15:53:12+02:00 (8 years ago)
Author:
michael2402
Message:

See #13636: Add automated clipping to MapViewPath.

Location:
trunk/src/org/openstreetmap/josm/gui
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/MapViewState.java

    r10968 r11026  
    2424import org.openstreetmap.josm.gui.download.DownloadDialog;
    2525import org.openstreetmap.josm.tools.CheckParameterUtil;
     26import org.openstreetmap.josm.tools.Geometry;
    2627import org.openstreetmap.josm.tools.bugreport.BugReport;
    2728
     
    5859     */
    5960    public static final int OUTSIDE_RIGHT = 8;
     61
     62    /**
     63     * Additional pixels outside the view for where to start clipping.
     64     */
     65    private static final int CLIP_BOUNDS = 50;
    6066
    6167    private final transient Projecting projecting;
     
    257263        return new AffineTransform(1.0 / scale, 0.0, 0.0, -1.0 / scale, -topLeft.east() / scale,
    258264                topLeft.north() / scale);
     265    }
     266
     267    /**
     268     * Gets a rectangle that is several pixel bigger than the view. It is used to define the view clipping.
     269     * @return The rectangle.
     270     */
     271    public MapViewRectangle getViewClipRectangle() {
     272        return getForView(-CLIP_BOUNDS, -CLIP_BOUNDS).rectTo(getForView(getViewWidth() + CLIP_BOUNDS, getViewHeight() + CLIP_BOUNDS));
    259273    }
    260274
     
    665679            return getInView().intersects(getViewArea().getInView());
    666680        }
     681
     682        /**
     683         * Gets the entry point at which a line between start and end enters the current view.
     684         * @param start The start
     685         * @param end The end
     686         * @return The entry point or <code>null</code> if the line does not intersect this view.
     687         */
     688        public MapViewPoint getLineEntry(MapViewPoint start, MapViewPoint end) {
     689            ProjectionBounds bounds = getProjectionBounds();
     690            if (bounds.contains(start.getEastNorth())) {
     691                return start;
     692            }
     693
     694            double dx = end.getEastNorth().east() - start.getEastNorth().east();
     695            double boundX = dx > 0 ? bounds.minEast : bounds.maxEast;
     696            EastNorth borderIntersection = Geometry.getSegmentSegmentIntersection(start.getEastNorth(), end.getEastNorth(),
     697                    new EastNorth(boundX, bounds.minNorth),
     698                    new EastNorth(boundX, bounds.maxNorth));
     699            if (borderIntersection != null) {
     700                return getPointFor(borderIntersection);
     701            }
     702
     703            double dy = end.getEastNorth().north() - start.getEastNorth().north();
     704            double boundY = dy > 0 ? bounds.minNorth : bounds.maxNorth;
     705            borderIntersection = Geometry.getSegmentSegmentIntersection(start.getEastNorth(), end.getEastNorth(),
     706                    new EastNorth(bounds.minEast, boundY),
     707                    new EastNorth(bounds.maxEast, boundY));
     708            if (borderIntersection != null) {
     709                return getPointFor(borderIntersection);
     710            }
     711
     712            return null;
     713        }
    667714    }
    668715
  • trunk/src/org/openstreetmap/josm/gui/draw/MapViewPath.java

    r10875 r11026  
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.gui.draw;
     3
     4import java.awt.geom.Point2D;
     5import java.text.MessageFormat;
    36
    47import org.openstreetmap.josm.data.coor.EastNorth;
     
    710import org.openstreetmap.josm.gui.MapViewState;
    811import org.openstreetmap.josm.gui.MapViewState.MapViewPoint;
     12import org.openstreetmap.josm.gui.MapViewState.MapViewRectangle;
    913
    1014/**
    1115 * This is a version of a java Path2D that allows you to add points to it by simply giving their east/north, lat/lon or node coordinates.
     16 * <p>
     17 * Paths far outside the view area are automatically clipped to increase performance.
    1218 * @author Michael Zangl
    1319 * @since 10875
     
    6167    /**
    6268     * Draw a line to the node.
     69     * <p>
     70     * line clamping to view is done automatically.
    6371     * @param n The node
    6472     * @return this for easy chaining.
     
    7179    /**
    7280     * Draw a line to the position.
     81     * <p>
     82     * line clamping to view is done automatically.
    7383     * @param eastNorth The position
    7484     * @return this for easy chaining.
     
    8191    @Override
    8292    public MapViewPath lineTo(MapViewPoint p) {
    83         super.lineTo(p);
     93        Point2D currentPoint = getCurrentPoint();
     94        if (currentPoint == null) {
     95            throw new IllegalStateException("Path not started yet.");
     96        }
     97        MapViewPoint current = state.getForView(currentPoint.getX(), currentPoint.getY());
     98        MapViewPoint end = p;
     99
     100        MapViewRectangle clip = state.getViewClipRectangle();
     101        MapViewPoint entry = clip.getLineEntry(current, end);
     102        if (entry == null) {
     103            // skip this one - outside the view.
     104            super.moveTo(end);
     105        } else {
     106            if (!entry.equals(current)) {
     107                super.moveTo(entry);
     108            }
     109            MapViewPoint exit = clip.getLineEntry(end, current);
     110            if (exit == null) {
     111                throw new AssertionError(MessageFormat.format(
     112                        "getLineEntry produces wrong results when doing the reverse lookup. Attempt: {0}->{1}",
     113                        end.getEastNorth(), current.getEastNorth()));
     114            }
     115            super.lineTo(exit);
     116            if (!exit.equals(end)) {
     117                super.moveTo(end);
     118            }
     119        }
    84120        return this;
    85121    }
Note: See TracChangeset for help on using the changeset viewer.