Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPaintSettings.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPaintSettings.java	(revision 9062)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPaintSettings.java	(revision 9063)
@@ -53,4 +53,9 @@
     /** Preference: width of unclosed area highlight */
     private double unclosedAreaHighlightWidth;
+    /** Preference: parameter to avoid partial fill on small area objects:
+     * If more than a certain percentage of the total area would be filled by 
+     * partial fill, then fill this area completely (avoiding narrow gap in the
+     * center) */
+    private double partialFillThreshold;
     /** Color Preference for selected objects */
     private Color selectedColor;
@@ -112,4 +117,5 @@
         unclosedAreaHighlight = Main.pref.getBoolean("draw.unclosed_area_partial_fill_highlight", true);
         unclosedAreaHighlightWidth = Main.pref.getDouble("draw.unclosed_area_partial_fill_highlight.width", 80);
+        partialFillThreshold = Main.pref.getDouble("draw.area.partial_fill_threshold", 50);
     }
 
@@ -363,5 +369,5 @@
 
     /**
-     * Returns the width of unclosed area highlight
+     * Returns the width of unclosed area highlight.
      * @return the width of unclosed area highlight
      */
@@ -369,3 +375,15 @@
         return unclosedAreaHighlightWidth;
     }
+
+    /**
+     * Returns the partial fill threshold.
+     * This parameter is used to avoid partial fill on small area objects:
+     * If more than a certain percentage of the total area would be filled by 
+     * partial fill, then fill this area completely (avoiding narrow gap in the
+     * center)
+     * @return the partial fill threshold
+     */
+    public double getPartialFillThreshold() {
+        return partialFillThreshold;
+    }
 }
Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java	(revision 9062)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java	(revision 9063)
@@ -75,4 +75,6 @@
 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector;
 import org.openstreetmap.josm.tools.CompositeList;
+import org.openstreetmap.josm.tools.Geometry;
+import org.openstreetmap.josm.tools.Geometry.AreaAndPerimeter;
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.Pair;
@@ -335,4 +337,5 @@
     private boolean isUnclosedAreaHighlight;
     private double unclosedAreaHighlightWidth;
+    private double partialFillThreshold;
 
     private Font orderFont;
@@ -465,5 +468,5 @@
      * far to fill from the boundary towards the center of the area;
      * if null, area will be filled completely
-     * @param unClosedHighlight true, if the fact that the way / multipolygon is not
+     * @param unclosedHighlight true, if the fact that the way / multipolygon is not
      * properly closed should be highlighted; this parameter is only used
      * for partial fill ({@code extent != null}), otherwise it is ignored 
@@ -471,5 +474,5 @@
      * @param text The text to write on the area.
      */
-    protected void drawArea(OsmPrimitive osm, Path2D.Double path, Color color, MapImage fillImage, Float extent, boolean unClosedHighlight,
+    protected void drawArea(OsmPrimitive osm, Path2D.Double path, Color color, MapImage fillImage, Float extent, boolean unclosedHighlight,
             boolean disabled, TextElement text) {
 
@@ -486,5 +489,5 @@
                     g.fill(area);
                 } else {
-                    if (unClosedHighlight) {
+                    if (unclosedHighlight) {
                         g.setStroke(new BasicStroke((int)(unclosedAreaHighlightWidth / 100 * extent),
                                 BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
@@ -509,5 +512,5 @@
                     g.fill(area);
                 } else {
-                    if (unClosedHighlight) {
+                    if (unclosedHighlight) {
                         g.setStroke(new BasicStroke((int)(unclosedAreaHighlightWidth / 100 * extent),
                                 BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
@@ -622,9 +625,20 @@
                     continue;
                 }
+                boolean unclosedHighlight = false;
+                if (extent != null) {
+                    if (pd.isClosed()) {
+                        AreaAndPerimeter ap = pd.getAreaAndPerimeter();
+                        // if partial fill would only leave a small gap in the center ...
+                        if (ap.getPerimeter() * extent * circum / 100 > partialFillThreshold / 100 * ap.getArea()) {
+                            // ... turn it off and fill completely
+                            extent = null;
+                        }
+                    } else {
+                        unclosedHighlight = isUnclosedAreaHighlight;
+                    }
+                }
                 drawArea(r, p,
                         pd.selected ? paintSettings.getRelationSelectedColor(color.getAlpha()) : color,
-                        fillImage, extent,
-                        isUnclosedAreaHighlight && extent != null && !pd.isClosed(),
-                        disabled, text);
+                        fillImage, extent, unclosedHighlight, disabled, text);
             }
         }
@@ -643,4 +657,12 @@
      */
     public void drawArea(Way w, Color color, MapImage fillImage, Float extent, boolean disabled, TextElement text) {
+        if (extent != null && w.isClosed()) {
+            AreaAndPerimeter ap = Geometry.getAreaAndPerimeter(w.getNodes());
+            // if partial fill would only leave a small gap in the center ...
+            if (ap.getPerimeter() * extent * circum / 100 > partialFillThreshold / 100 * ap.getArea()) {
+                // ... turn it off and fill completely
+                extent = null;
+            }
+        }
         drawArea(w, getPath(w), color, fillImage, extent, isUnclosedAreaHighlight && !w.isClosed(), disabled, text);
     }
@@ -1500,4 +1522,5 @@
         isUnclosedAreaHighlight = paintSettings.isUnclosedAreaHighlight();
         unclosedAreaHighlightWidth = paintSettings.getUnclosedAreaHighlightWidth();
+        partialFillThreshold = paintSettings.getPartialFillThreshold();
         orderFont = new Font(Main.pref.get("mappaint.font", "Droid Sans"), Font.PLAIN, Main.pref.getInteger("mappaint.fontsize", 8));
 
Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java	(revision 9062)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java	(revision 9063)
@@ -3,5 +3,4 @@
 
 import java.awt.geom.Path2D;
-import java.awt.geom.Path2D.Double;
 import java.awt.geom.PathIterator;
 import java.awt.geom.Rectangle2D;
@@ -27,4 +26,6 @@
 import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent;
 import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.PolyData.Intersection;
+import org.openstreetmap.josm.tools.Geometry;
+import org.openstreetmap.josm.tools.Geometry.AreaAndPerimeter;
 
 /**
@@ -244,5 +245,5 @@
         public PolyData(PolyData copy) {
             this.selected = copy.selected;
-            this.poly = (Double) copy.poly.clone();
+            this.poly = (Path2D.Double) copy.poly.clone();
             this.wayIds = Collections.unmodifiableCollection(copy.wayIds);
             this.nodes = new ArrayList<>(copy.nodes);
@@ -368,4 +369,16 @@
             }
             return true;
+        }
+
+        public AreaAndPerimeter getAreaAndPerimeter() {
+            AreaAndPerimeter ap = Geometry.getAreaAndPerimeter(nodes);
+            double area = ap.getArea();
+            double perimeter = ap.getPerimeter();
+            for (PolyData inner : inners) {
+                AreaAndPerimeter apInner = inner.getAreaAndPerimeter();
+                area -= apInner.getArea();
+                perimeter += apInner.getPerimeter();
+            }
+            return new AreaAndPerimeter(area, perimeter);
         }
     }
Index: trunk/src/org/openstreetmap/josm/tools/Geometry.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/Geometry.java	(revision 9062)
+++ trunk/src/org/openstreetmap/josm/tools/Geometry.java	(revision 9063)
@@ -951,3 +951,52 @@
         return false;
     }
+
+    /**
+     * Data class to hold two double values (area and perimeter of a polygon).
+     */
+    public static class AreaAndPerimeter {
+        private final double area;
+        private final double perimeter;
+
+        public AreaAndPerimeter(double area, double perimeter) {
+            this.area = area;
+            this.perimeter = perimeter;
+        }
+
+        public double getArea() {
+            return area;
+        }
+
+        public double getPerimeter() {
+            return perimeter;
+        }
+    }
+
+    /**
+     * Calculate area and perimeter length of a polygon.
+     * 
+     * Uses current projection; units are that of the projected coordinates.
+     * 
+     * @param nodes the list of nodes representing the polygon (must be
+     * closed, i.e. first node equals last node)
+     * @return area and perimeter
+     */
+    public static AreaAndPerimeter getAreaAndPerimeter(List<Node> nodes) {
+        if (nodes.get(0) != nodes.get(nodes.size() - 1)) {
+            throw new IllegalArgumentException();
+        }
+        double area = 0;
+        double perimeter = 0;
+        Node lastN = null;
+        for (Node n : nodes) {
+            if (lastN != null) {
+                EastNorth p1 = lastN.getEastNorth();
+                EastNorth p2 = n.getEastNorth();
+                area += p1.east() * p2.north() - p2.east() * p1.north();
+                perimeter += p1.distance(p2);
+            }
+            lastN = n;
+        }
+        return new AreaAndPerimeter(Math.abs(area) / 2, perimeter);
+    }
 }
