- Timestamp:
- 2015-11-25T09:54:02+01:00 (9 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPaintSettings.java
r9061 r9063 53 53 /** Preference: width of unclosed area highlight */ 54 54 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; 55 60 /** Color Preference for selected objects */ 56 61 private Color selectedColor; … … 112 117 unclosedAreaHighlight = Main.pref.getBoolean("draw.unclosed_area_partial_fill_highlight", true); 113 118 unclosedAreaHighlightWidth = Main.pref.getDouble("draw.unclosed_area_partial_fill_highlight.width", 80); 119 partialFillThreshold = Main.pref.getDouble("draw.area.partial_fill_threshold", 50); 114 120 } 115 121 … … 363 369 364 370 /** 365 * Returns the width of unclosed area highlight 371 * Returns the width of unclosed area highlight. 366 372 * @return the width of unclosed area highlight 367 373 */ … … 369 375 return unclosedAreaHighlightWidth; 370 376 } 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 } 371 389 } -
trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java
r9061 r9063 75 75 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector; 76 76 import org.openstreetmap.josm.tools.CompositeList; 77 import org.openstreetmap.josm.tools.Geometry; 78 import org.openstreetmap.josm.tools.Geometry.AreaAndPerimeter; 77 79 import org.openstreetmap.josm.tools.ImageProvider; 78 80 import org.openstreetmap.josm.tools.Pair; … … 335 337 private boolean isUnclosedAreaHighlight; 336 338 private double unclosedAreaHighlightWidth; 339 private double partialFillThreshold; 337 340 338 341 private Font orderFont; … … 465 468 * far to fill from the boundary towards the center of the area; 466 469 * if null, area will be filled completely 467 * @param un ClosedHighlight true, if the fact that the way / multipolygon is not470 * @param unclosedHighlight true, if the fact that the way / multipolygon is not 468 471 * properly closed should be highlighted; this parameter is only used 469 472 * for partial fill ({@code extent != null}), otherwise it is ignored … … 471 474 * @param text The text to write on the area. 472 475 */ 473 protected void drawArea(OsmPrimitive osm, Path2D.Double path, Color color, MapImage fillImage, Float extent, boolean un ClosedHighlight,476 protected void drawArea(OsmPrimitive osm, Path2D.Double path, Color color, MapImage fillImage, Float extent, boolean unclosedHighlight, 474 477 boolean disabled, TextElement text) { 475 478 … … 486 489 g.fill(area); 487 490 } else { 488 if (un ClosedHighlight) {491 if (unclosedHighlight) { 489 492 g.setStroke(new BasicStroke((int)(unclosedAreaHighlightWidth / 100 * extent), 490 493 BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)); … … 509 512 g.fill(area); 510 513 } else { 511 if (un ClosedHighlight) {514 if (unclosedHighlight) { 512 515 g.setStroke(new BasicStroke((int)(unclosedAreaHighlightWidth / 100 * extent), 513 516 BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)); … … 622 625 continue; 623 626 } 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 } 624 640 drawArea(r, p, 625 641 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); 629 643 } 630 644 } … … 643 657 */ 644 658 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 } 645 667 drawArea(w, getPath(w), color, fillImage, extent, isUnclosedAreaHighlight && !w.isClosed(), disabled, text); 646 668 } … … 1500 1522 isUnclosedAreaHighlight = paintSettings.isUnclosedAreaHighlight(); 1501 1523 unclosedAreaHighlightWidth = paintSettings.getUnclosedAreaHighlightWidth(); 1524 partialFillThreshold = paintSettings.getPartialFillThreshold(); 1502 1525 orderFont = new Font(Main.pref.get("mappaint.font", "Droid Sans"), Font.PLAIN, Main.pref.getInteger("mappaint.fontsize", 8)); 1503 1526 -
trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java
r9061 r9063 3 3 4 4 import java.awt.geom.Path2D; 5 import java.awt.geom.Path2D.Double;6 5 import java.awt.geom.PathIterator; 7 6 import java.awt.geom.Rectangle2D; … … 27 26 import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent; 28 27 import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.PolyData.Intersection; 28 import org.openstreetmap.josm.tools.Geometry; 29 import org.openstreetmap.josm.tools.Geometry.AreaAndPerimeter; 29 30 30 31 /** … … 244 245 public PolyData(PolyData copy) { 245 246 this.selected = copy.selected; 246 this.poly = ( Double) copy.poly.clone();247 this.poly = (Path2D.Double) copy.poly.clone(); 247 248 this.wayIds = Collections.unmodifiableCollection(copy.wayIds); 248 249 this.nodes = new ArrayList<>(copy.nodes); … … 368 369 } 369 370 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); 370 383 } 371 384 } -
trunk/src/org/openstreetmap/josm/tools/Geometry.java
r9062 r9063 951 951 return false; 952 952 } 953 954 /** 955 * Data class to hold two double values (area and perimeter of a polygon). 956 */ 957 public static class AreaAndPerimeter { 958 private final double area; 959 private final double perimeter; 960 961 public AreaAndPerimeter(double area, double perimeter) { 962 this.area = area; 963 this.perimeter = perimeter; 964 } 965 966 public double getArea() { 967 return area; 968 } 969 970 public double getPerimeter() { 971 return perimeter; 972 } 973 } 974 975 /** 976 * Calculate area and perimeter length of a polygon. 977 * 978 * Uses current projection; units are that of the projected coordinates. 979 * 980 * @param nodes the list of nodes representing the polygon (must be 981 * closed, i.e. first node equals last node) 982 * @return area and perimeter 983 */ 984 public static AreaAndPerimeter getAreaAndPerimeter(List<Node> nodes) { 985 if (nodes.get(0) != nodes.get(nodes.size() - 1)) { 986 throw new IllegalArgumentException(); 987 } 988 double area = 0; 989 double perimeter = 0; 990 Node lastN = null; 991 for (Node n : nodes) { 992 if (lastN != null) { 993 EastNorth p1 = lastN.getEastNorth(); 994 EastNorth p2 = n.getEastNorth(); 995 area += p1.east() * p2.north() - p2.east() * p1.north(); 996 perimeter += p1.distance(p2); 997 } 998 lastN = n; 999 } 1000 return new AreaAndPerimeter(Math.abs(area) / 2, perimeter); 1001 } 953 1002 }
Note:
See TracChangeset
for help on using the changeset viewer.