Ticket #17614: 17614.patch

File 17614.patch, 6.3 KB (added by GerdP, 7 years ago)
  • src/org/openstreetmap/josm/data/osm/WaySegment.java

     
    1212    /**
    1313     * The way.
    1414     */
    15     public Way way;
     15    public final Way way;
    1616
    1717    /**
    1818     * The index of one of the 2 nodes in the way.  The other node has the
    1919     * index <code>lowerIndex + 1</code>.
    2020     */
    21     public int lowerIndex;
     21    public final int lowerIndex;
    2222
    2323    /**
    2424     * Constructs a new {@code WaySegment}.
  • src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java

     
    471471            // the two polygons may only share one or more segments but they may also intersect
    472472            Area a1 = new Area(pd1.get());
    473473            Area a2 = new Area(pd2.get());
    474             PolygonIntersection areaRes = Geometry.polygonIntersection(a1, a2, 1e-6);
     474            PolygonIntersection areaRes = Geometry.polygonIntersection(a1, a2);
    475475            if (areaRes == PolygonIntersection.OUTSIDE)
    476476                return ExtPolygonIntersection.OUTSIDE;
    477477            return ExtPolygonIntersection.CROSSING;
  • src/org/openstreetmap/josm/tools/Geometry.java

     
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.tools;
    33
    4 import java.awt.Rectangle;
    54import java.awt.geom.Area;
    65import java.awt.geom.Line2D;
    76import java.awt.geom.Path2D;
     7import java.awt.geom.PathIterator;
     8import java.awt.geom.Rectangle2D;
    89import java.math.BigDecimal;
    910import java.math.MathContext;
    1011import java.util.ArrayList;
     
    7172        CROSSING
    7273    }
    7374
     75    /** threshold value for size of intersection area given in east/north space */
     76    public static final double INTERSECTION_EPS_EAST_NORTH = 0.01;
     77
    7478    /**
    7579     * Will find all intersection and add nodes there for list of given ways.
    7680     * Handles self-intersections too.
     
    577581    public static PolygonIntersection polygonIntersection(List<? extends INode> first, List<? extends INode> second) {
    578582        Area a1 = getArea(first);
    579583        Area a2 = getArea(second);
    580         return polygonIntersection(a1, a2);
     584        return polygonIntersection(a1, a2, INTERSECTION_EPS_EAST_NORTH);
    581585    }
    582586
    583587    /**
    584      * Tests if two polygons intersect.
     588     * Tests if two polygons intersect. It is assumed that the area is given in East North points.
    585589     * @param a1 Area of first polygon
    586590     * @param a2 Area of second polygon
    587591     * @return intersection kind
     
    588592     * @since 6841
    589593     */
    590594    public static PolygonIntersection polygonIntersection(Area a1, Area a2) {
    591         return polygonIntersection(a1, a2, 1.0);
     595        return polygonIntersection(a1, a2, INTERSECTION_EPS_EAST_NORTH);
    592596    }
    593597
    594598    /**
     
    603607        Area inter = new Area(a1);
    604608        inter.intersect(a2);
    605609
    606         Rectangle bounds = inter.getBounds();
    607 
    608         if (inter.isEmpty() || bounds.getHeight()*bounds.getWidth() <= eps) {
     610        if (inter.isEmpty() || !checkIntersection(inter, eps)) {
    609611            return PolygonIntersection.OUTSIDE;
    610612        } else if (a2.getBounds2D().contains(a1.getBounds2D()) && inter.equals(a1)) {
    611613            return PolygonIntersection.FIRST_INSIDE_SECOND;
     
    617619    }
    618620
    619621    /**
     622     * Check an intersection area which might describe multiple small polygons.
     623     * Return true if any of the polygons is bigger than the given threshold.
     624     * @param inter the intersection area
     625     * @param eps an area threshold, everything below is considered an empty intersection
     626     * @return true if any of the polygons is bigger than the given threshold.
     627     */
     628    private static boolean checkIntersection(Area inter, double eps) {
     629        PathIterator pit = inter.getPathIterator(null);
     630        double[] res = new double[6];
     631        Rectangle2D r = new Rectangle2D.Double();
     632        while (!pit.isDone()) {
     633            int type = pit.currentSegment(res);
     634            switch (type) {
     635            case PathIterator.SEG_MOVETO:
     636                r = new Rectangle2D.Double(res[0], res[1], 0, 0);
     637                break;
     638            case PathIterator.SEG_LINETO:
     639                r.add(res[0], res[1]);
     640                break;
     641            case PathIterator.SEG_CLOSE:
     642                if (r.getWidth() > eps || r.getHeight() > eps)
     643                    return true;
     644                break;
     645            default:
     646                break;
     647            }
     648            pit.next();
     649        }
     650        if (inter.getBounds2D().getWidth() > eps || inter.getBounds2D().getHeight() > eps) {
     651            long dd = 4;
     652        }
     653        return false;
     654    }
     655
     656    /**
    620657     * Tests if point is inside a polygon. The polygon can be self-intersecting. In such case the contains function works in xor-like manner.
    621658     * @param polygonNodes list of nodes from polygon path.
    622659     * @param point the point to test
     
    777814     * Returns angle of a corner defined with 3 point coordinates.
    778815     *
    779816     * @param p1 first point
    780      * @param p2 Common endpoint
     817     * @param common Common end point
    781818     * @param p3 third point
    782819     * @return Angle in radians (-pi, pi]
    783820     */
    784     public static double getCornerAngle(EastNorth p1, EastNorth p2, EastNorth p3) {
     821    public static double getCornerAngle(EastNorth p1, EastNorth common, EastNorth p3) {
    785822
    786823        CheckParameterUtil.ensure(p1, "p1", EastNorth::isValid);
    787         CheckParameterUtil.ensure(p2, "p2", EastNorth::isValid);
     824        CheckParameterUtil.ensure(common, "p2", EastNorth::isValid);
    788825        CheckParameterUtil.ensure(p3, "p3", EastNorth::isValid);
    789826
    790         Double result = getSegmentAngle(p2, p1) - getSegmentAngle(p2, p3);
     827        double result = getSegmentAngle(common, p1) - getSegmentAngle(common, p3);
    791828        if (result <= -Math.PI) {
    792829            result += 2 * Math.PI;
    793830        }