Changeset 14583 in josm for trunk


Ignore:
Timestamp:
2018-12-22T08:49:30+01:00 (5 months ago)
Author:
GerdP
Message:

fix #17119: Improve rendering time of partly visible complex shapes

Clip all areas (shapes) to the extended visible area so that complex shapes are reduced to those points which are effective for rendering. Should have no effect on the rendered image but improves performance when many nodes of the shape are outside of the visible area.

Location:
trunk/src/org/openstreetmap/josm
Files:
1 added
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java

    r14557 r14583  
    8888import org.openstreetmap.josm.tools.JosmRuntimeException;
    8989import org.openstreetmap.josm.tools.Logging;
     90import org.openstreetmap.josm.tools.ShapeClipper;
    9091import org.openstreetmap.josm.tools.Utils;
    9192import org.openstreetmap.josm.tools.bugreport.BugReport;
     
    437438     */
    438439    protected void drawArea(MapViewPath path, Color color,
    439             MapImage fillImage, Float extent, Path2D.Double pfClip, boolean disabled) {
     440            MapImage fillImage, Float extent, MapViewPath pfClip, boolean disabled) {
    440441        if (!isOutlineOnly && color.getAlpha() != 0) {
    441442            Shape area = path;
     
    478479     *
    479480     */
    480     private void computeFill(Shape shape, Float extent, Path2D.Double pfClip, float mitterLimit) {
     481    private void computeFill(Shape shape, Float extent, MapViewPath pfClip, float mitterLimit) {
    481482        if (extent == null) {
    482483            g.fill(shape);
     
    485486            Shape clip = shape;
    486487            if (pfClip != null) {
    487                 clip = pfClip.createTransformedShape(mapState.getAffineTransform());
     488                clip = pfClip;
    488489            }
    489490            g.clip(clip);
     
    515516                    continue;
    516517                }
    517                 MapViewPath p = new MapViewPath(mapState);
    518                 p.appendFromEastNorth(pd.get());
    519                 p.setWindingRule(Path2D.WIND_EVEN_ODD);
    520                 Path2D.Double pfClip = null;
     518                MapViewPath p = shapeEastNorthToMapView(pd.get());
     519                MapViewPath pfClip = null;
    521520                if (extent != null) {
    522521                    if (!usePartialFill(pd.getAreaAndPerimeter(null), extent, extentThreshold)) {
    523522                        extent = null;
    524523                    } else if (!pd.isClosed()) {
    525                         pfClip = getPFClip(pd, extent * scale);
     524                        pfClip = shapeEastNorthToMapView(getPFClip(pd, extent * scale));
    526525                    }
    527526                }
     
    531530            }
    532531        }
     532    }
     533
     534    /**
     535     * Convert shape in EastNorth coordinates to MapViewPath and remove invisible parts.
     536     * For complex shapes this improves performance drastically because the methods in Graphics2D.clip() and Graphics2D.draw() are rather slow.
     537     * @param shape the shape to convert
     538     * @return the converted shape
     539     */
     540    private MapViewPath shapeEastNorthToMapView(Path2D.Double shape) {
     541        MapViewPath convertedShape = null;
     542        if (shape != null) {
     543            convertedShape = new MapViewPath(mapState);
     544            convertedShape.appendFromEastNorth(shape);
     545            convertedShape.setWindingRule(Path2D.WIND_EVEN_ODD);
     546
     547            Rectangle2D extViewBBox = mapState.getViewClipRectangle().getInView();
     548            if (!extViewBBox.contains(convertedShape.getBounds2D())) {
     549                // remove invisible parts of shape
     550                Path2D.Double clipped = ShapeClipper.clipShape(convertedShape, extViewBBox);
     551                if (clipped != null) {
     552                    convertedShape.reset();
     553                    convertedShape.append(clipped, false);
     554                }
     555            }
     556        }
     557        return convertedShape;
    533558    }
    534559
     
    547572     */
    548573    public void drawArea(IWay<?> w, Color color, MapImage fillImage, Float extent, Float extentThreshold, boolean disabled) {
    549         Path2D.Double pfClip = null;
     574        MapViewPath pfClip = null;
    550575        if (extent != null) {
    551576            if (!usePartialFill(Geometry.getAreaAndPerimeter(w.getNodes()), extent, extentThreshold)) {
    552577                extent = null;
    553578            } else if (!w.isClosed()) {
    554                 pfClip = getPFClip(w, extent * scale);
     579                pfClip = shapeEastNorthToMapView(getPFClip(w, extent * scale));
    555580            }
    556581        }
Note: See TracChangeset for help on using the changeset viewer.