Changeset 9099 in josm for trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java
- Timestamp:
- 2015-12-11T17:36:59+01:00 (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java
r9082 r9099 336 336 private boolean showIcons; 337 337 private boolean isOutlineOnly; 338 private double partialFillThreshold;339 338 340 339 private Font orderFont; … … 467 466 * far to fill from the boundary towards the center of the area; 468 467 * if null, area will be filled completely 469 * @param pfClip clipping area for partial fill 468 * @param pfClip clipping area for partial fill (only needed for unclosed 469 * polygons) 470 470 * @param disabled If this should be drawn with a special disabled style. 471 471 * @param text The text to write on the area. … … 492 492 } 493 493 g.clip(clip); 494 g.setStroke(new BasicStroke(2 * extent, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER ));494 g.setStroke(new BasicStroke(2 * extent, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 4)); 495 495 g.draw(area); 496 496 g.setClip(oldClip); … … 607 607 * far to fill from the boundary towards the center of the area; 608 608 * if null, area will be filled completely 609 * @param extentThreshold if not null, determines if the partial filled should 610 * be replaced by plain fill, when it covers a certain fraction of the total area 609 611 * @param disabled If this should be drawn with a special disabled style. 610 612 * @param text The text to write on the area. 611 613 */ 612 public void drawArea(Relation r, Color color, MapImage fillImage, Float extent, boolean disabled, TextElement text) {614 public void drawArea(Relation r, Color color, MapImage fillImage, Float extent, Float extentThreshold, boolean disabled, TextElement text) { 613 615 Multipolygon multipolygon = MultipolygonCache.getInstance().get(nc, r); 614 616 if (!r.isDisabled() && !multipolygon.getOuterWays().isEmpty()) { … … 620 622 } 621 623 if (extent != null) { 622 if (pd.isClosed()) { 623 AreaAndPerimeter ap = pd.getAreaAndPerimeter(); 624 // if partial fill would only leave a small gap in the center ... 625 if (ap.getPerimeter() * extent * scale > partialFillThreshold / 100 * ap.getArea()) { 626 // ... turn it off and fill completely 627 extent = null; 628 } 629 } else { 624 if (!usePartialFill(pd.getAreaAndPerimeter(), extent, extentThreshold)) { 625 extent = null; 626 } else if (!pd.isClosed()) { 630 627 pfClip = getPFClip(pd, extent * scale); 631 628 } … … 646 643 * far to fill from the boundary towards the center of the area; 647 644 * if null, area will be filled completely 645 * @param extentThreshold if not null, determines if the partial filled should 646 * be replaced by plain fill, when it covers a certain fraction of the total area 648 647 * @param disabled If this should be drawn with a special disabled style. 649 648 * @param text The text to write on the area. 650 649 */ 651 public void drawArea(Way w, Color color, MapImage fillImage, Float extent, boolean disabled, TextElement text) {650 public void drawArea(Way w, Color color, MapImage fillImage, Float extent, Float extentThreshold, boolean disabled, TextElement text) { 652 651 Path2D.Double pfClip = null; 653 652 if (extent != null) { 654 if (w.isClosed()) { 655 AreaAndPerimeter ap = Geometry.getAreaAndPerimeter(w.getNodes()); 656 // if partial fill would only leave a small gap in the center ... 657 if (ap.getPerimeter() * extent * scale > partialFillThreshold / 100 * ap.getArea()) { 658 // ... turn it off and fill completely 659 extent = null; 660 } 661 } else { 653 if (!usePartialFill(Geometry.getAreaAndPerimeter(w.getNodes()), extent, extentThreshold)) { 654 extent = null; 655 } else if (!w.isClosed()) { 662 656 pfClip = getPFClip(w, extent * scale); 663 657 } 664 658 } 665 659 drawArea(w, getPath(w), color, fillImage, extent, pfClip, disabled, text); 660 } 661 662 /** 663 * Determine, if partial fill should be turned off for this object, because 664 * only a small unfilled gap in the center of the area would be left. 665 * 666 * This is used to get a cleaner look for urban regions with many small 667 * areas like buildings, etc. 668 * @param ap the area and the perimeter of the object 669 * @param extent the "width" of partial fill 670 * @param threshold when the partial fill covers that much of the total 671 * area, the partial fill is turned off; can be greater than 100% as the 672 * covered area is estimated as <code>perimeter * extent</code> 673 * @return true, if the partial fill should be used, false otherwise 674 */ 675 private boolean usePartialFill(AreaAndPerimeter ap, float extent, Float threshold) { 676 if (threshold == null) return true; 677 return ap.getPerimeter() * extent * scale < threshold * ap.getArea(); 666 678 } 667 679 … … 1519 1531 showIcons = paintSettings.getShowIconsDistance() > circum; 1520 1532 isOutlineOnly = paintSettings.isOutlineOnly(); 1521 partialFillThreshold = paintSettings.getPartialFillThreshold();1522 1533 orderFont = new Font(Main.pref.get("mappaint.font", "Droid Sans"), Font.PLAIN, Main.pref.getInteger("mappaint.fontsize", 8)); 1523 1534 … … 1596 1607 } 1597 1608 1609 /** 1610 * Fix the clipping area of unclosed polygons for partial fill. 1611 * 1612 * The current algorithm for partial fill simply strokes the polygon with a 1613 * large stroke width after masking the outside with a clipping area. 1614 * This works, but for unclosed polygons, the mask can crop the corners at 1615 * both ends (see #12104). 1616 * 1617 * This method fixes the clipping area by sort of adding the corners to the 1618 * clip outline. 1619 * 1620 * @param clip the clipping area to modify (initially empty) 1621 * @param nodes nodes of the polygon 1622 * @param extent the extent 1623 */ 1598 1624 private static void buildPFClip(Path2D.Double clip, List<Node> nodes, double extent) { 1599 1625 boolean initial = true; … … 1629 1655 } 1630 1656 1657 /** 1658 * Get the point to add to the clipping area for partial fill of unclosed polygons. 1659 * 1660 * <code>(p1,p2)</code> is the first or last way segment and <code>p3</code> the 1661 * opposite endpoint. 1662 * 1663 * @param p1 1st point 1664 * @param p2 2nd point 1665 * @param p3 3rd point 1666 * @param extent the extent 1667 * @return a point q, such that p1,p2,q form a right angle 1668 * and the distance of q to p2 is <code>extent</code>. The point q lies on 1669 * the same side of the line p1,p2 as the point p3. 1670 * Returns null if p1,p2,p3 forms an angle greater 90 degrees. (In this case 1671 * the corner of the partial fill would not be cut off by the mask, so an 1672 * additional point is not necessary.) 1673 */ 1631 1674 private static EastNorth getPFDisplacedEndPoint(EastNorth p1, EastNorth p2, EastNorth p3, double extent) { 1632 1675 double dx1 = p2.getX() - p1.getX(); … … 1636 1679 if (dx1 * dx2 + dy1 * dy2 < 0) { 1637 1680 double len = Math.sqrt(dx1 * dx1 + dy1 * dy1); 1681 if (len == 0) return null; 1638 1682 double dxm = -dy1 * extent / len; 1639 1683 double dym = dx1 * extent / len;
Note:
See TracChangeset
for help on using the changeset viewer.