Ignore:
Timestamp:
2015-11-25T09:54:02+01:00 (8 years ago)
Author:
bastiK
Message:

mapcss: partial fill - if partial fill would only leave a small gap in the center, fill area completely (see #12104)

Location:
trunk/src/org/openstreetmap/josm/data/osm/visitor/paint
Files:
3 edited

Legend:

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

    r9061 r9063  
    5353    /** Preference: width of unclosed area highlight */
    5454    private double unclosedAreaHighlightWidth;
     55    /** Preference: parameter to avoid partial fill on small area objects:
     56     * If more than a certain percentage of the total area would be filled by
     57     * partial fill, then fill this area completely (avoiding narrow gap in the
     58     * center) */
     59    private double partialFillThreshold;
    5560    /** Color Preference for selected objects */
    5661    private Color selectedColor;
     
    112117        unclosedAreaHighlight = Main.pref.getBoolean("draw.unclosed_area_partial_fill_highlight", true);
    113118        unclosedAreaHighlightWidth = Main.pref.getDouble("draw.unclosed_area_partial_fill_highlight.width", 80);
     119        partialFillThreshold = Main.pref.getDouble("draw.area.partial_fill_threshold", 50);
    114120    }
    115121
     
    363369
    364370    /**
    365      * Returns the width of unclosed area highlight
     371     * Returns the width of unclosed area highlight.
    366372     * @return the width of unclosed area highlight
    367373     */
     
    369375        return unclosedAreaHighlightWidth;
    370376    }
     377
     378    /**
     379     * Returns the partial fill threshold.
     380     * This parameter is used to avoid partial fill on small area objects:
     381     * If more than a certain percentage of the total area would be filled by
     382     * partial fill, then fill this area completely (avoiding narrow gap in the
     383     * center)
     384     * @return the partial fill threshold
     385     */
     386    public double getPartialFillThreshold() {
     387        return partialFillThreshold;
     388    }
    371389}
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java

    r9061 r9063  
    7575import org.openstreetmap.josm.gui.mappaint.mapcss.Selector;
    7676import org.openstreetmap.josm.tools.CompositeList;
     77import org.openstreetmap.josm.tools.Geometry;
     78import org.openstreetmap.josm.tools.Geometry.AreaAndPerimeter;
    7779import org.openstreetmap.josm.tools.ImageProvider;
    7880import org.openstreetmap.josm.tools.Pair;
     
    335337    private boolean isUnclosedAreaHighlight;
    336338    private double unclosedAreaHighlightWidth;
     339    private double partialFillThreshold;
    337340
    338341    private Font orderFont;
     
    465468     * far to fill from the boundary towards the center of the area;
    466469     * if null, area will be filled completely
    467      * @param unClosedHighlight true, if the fact that the way / multipolygon is not
     470     * @param unclosedHighlight true, if the fact that the way / multipolygon is not
    468471     * properly closed should be highlighted; this parameter is only used
    469472     * for partial fill ({@code extent != null}), otherwise it is ignored
     
    471474     * @param text The text to write on the area.
    472475     */
    473     protected void drawArea(OsmPrimitive osm, Path2D.Double path, Color color, MapImage fillImage, Float extent, boolean unClosedHighlight,
     476    protected void drawArea(OsmPrimitive osm, Path2D.Double path, Color color, MapImage fillImage, Float extent, boolean unclosedHighlight,
    474477            boolean disabled, TextElement text) {
    475478
     
    486489                    g.fill(area);
    487490                } else {
    488                     if (unClosedHighlight) {
     491                    if (unclosedHighlight) {
    489492                        g.setStroke(new BasicStroke((int)(unclosedAreaHighlightWidth / 100 * extent),
    490493                                BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
     
    509512                    g.fill(area);
    510513                } else {
    511                     if (unClosedHighlight) {
     514                    if (unclosedHighlight) {
    512515                        g.setStroke(new BasicStroke((int)(unclosedAreaHighlightWidth / 100 * extent),
    513516                                BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
     
    622625                    continue;
    623626                }
     627                boolean unclosedHighlight = false;
     628                if (extent != null) {
     629                    if (pd.isClosed()) {
     630                        AreaAndPerimeter ap = pd.getAreaAndPerimeter();
     631                        // if partial fill would only leave a small gap in the center ...
     632                        if (ap.getPerimeter() * extent * circum / 100 > partialFillThreshold / 100 * ap.getArea()) {
     633                            // ... turn it off and fill completely
     634                            extent = null;
     635                        }
     636                    } else {
     637                        unclosedHighlight = isUnclosedAreaHighlight;
     638                    }
     639                }
    624640                drawArea(r, p,
    625641                        pd.selected ? paintSettings.getRelationSelectedColor(color.getAlpha()) : color,
    626                         fillImage, extent,
    627                         isUnclosedAreaHighlight && extent != null && !pd.isClosed(),
    628                         disabled, text);
     642                        fillImage, extent, unclosedHighlight, disabled, text);
    629643            }
    630644        }
     
    643657     */
    644658    public void drawArea(Way w, Color color, MapImage fillImage, Float extent, boolean disabled, TextElement text) {
     659        if (extent != null && w.isClosed()) {
     660            AreaAndPerimeter ap = Geometry.getAreaAndPerimeter(w.getNodes());
     661            // if partial fill would only leave a small gap in the center ...
     662            if (ap.getPerimeter() * extent * circum / 100 > partialFillThreshold / 100 * ap.getArea()) {
     663                // ... turn it off and fill completely
     664                extent = null;
     665            }
     666        }
    645667        drawArea(w, getPath(w), color, fillImage, extent, isUnclosedAreaHighlight && !w.isClosed(), disabled, text);
    646668    }
     
    15001522        isUnclosedAreaHighlight = paintSettings.isUnclosedAreaHighlight();
    15011523        unclosedAreaHighlightWidth = paintSettings.getUnclosedAreaHighlightWidth();
     1524        partialFillThreshold = paintSettings.getPartialFillThreshold();
    15021525        orderFont = new Font(Main.pref.get("mappaint.font", "Droid Sans"), Font.PLAIN, Main.pref.getInteger("mappaint.fontsize", 8));
    15031526
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java

    r9061 r9063  
    33
    44import java.awt.geom.Path2D;
    5 import java.awt.geom.Path2D.Double;
    65import java.awt.geom.PathIterator;
    76import java.awt.geom.Rectangle2D;
     
    2726import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent;
    2827import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.PolyData.Intersection;
     28import org.openstreetmap.josm.tools.Geometry;
     29import org.openstreetmap.josm.tools.Geometry.AreaAndPerimeter;
    2930
    3031/**
     
    244245        public PolyData(PolyData copy) {
    245246            this.selected = copy.selected;
    246             this.poly = (Double) copy.poly.clone();
     247            this.poly = (Path2D.Double) copy.poly.clone();
    247248            this.wayIds = Collections.unmodifiableCollection(copy.wayIds);
    248249            this.nodes = new ArrayList<>(copy.nodes);
     
    368369            }
    369370            return true;
     371        }
     372
     373        public AreaAndPerimeter getAreaAndPerimeter() {
     374            AreaAndPerimeter ap = Geometry.getAreaAndPerimeter(nodes);
     375            double area = ap.getArea();
     376            double perimeter = ap.getPerimeter();
     377            for (PolyData inner : inners) {
     378                AreaAndPerimeter apInner = inner.getAreaAndPerimeter();
     379                area -= apInner.getArea();
     380                perimeter += apInner.getPerimeter();
     381            }
     382            return new AreaAndPerimeter(area, perimeter);
    370383        }
    371384    }
Note: See TracChangeset for help on using the changeset viewer.