Ticket #8851: better_intersections.patch

File better_intersections.patch, 5.1 KB (added by akks, 13 years ago)
  • src/org/openstreetmap/josm/actions/JoinAreasAction.java

     
    314314     * Gets called whenever the shortcut is pressed or the menu entry is selected
    315315     * Checks whether the selected objects are suitable to join and joins them if so
    316316     */
     317    @Override
    317318    public void actionPerformed(ActionEvent e) {
    318319        LinkedList<Way> ways = new LinkedList<Way>(Main.main.getCurrentDataSet().getSelectedWays());
    319320
     
    12941295     * @return The list of relation with roles to add own relation to
    12951296     */
    12961297    private RelationRole addOwnMultigonRelation(Collection<Way> inner, Way outer) {
    1297         if (inner.size() == 0) return null;
     1298        if (inner.isEmpty()) return null;
    12981299        // Create new multipolygon relation and add all inner ways to it
    12991300        Relation newRel = new Relation();
    13001301        newRel.put("type", "multipolygon");
     
    13701371            cmds.add(new ChangeCommand(r.rel, newRel));
    13711372        }
    13721373
    1373         Relation newRel = null;
     1374        Relation newRel;
    13741375        switch (multiouters.size()) {
    13751376        case 0:
    13761377            return;
  • src/org/openstreetmap/josm/tools/Geometry.java

     
    5050
    5151        //stupid java, cannot instantiate array of generic classes..
    5252        @SuppressWarnings("unchecked")
    53         ArrayList<Node>[] newNodes = new ArrayList[ways.size()];
    54         BBox[] wayBounds = new BBox[ways.size()];
    55         boolean[] changedWays = new boolean[ways.size()];
     53        int n = ways.size();
     54        ArrayList<Node>[] newNodes = new ArrayList[n];
     55        BBox[] wayBounds = new BBox[n];
     56        boolean[] changedWays = new boolean[n];
    5657
    5758        Set<Node> intersectionNodes = new LinkedHashSet<Node>();
    5859
    5960        //copy node arrays for local usage.
    60         for (int pos = 0; pos < ways.size(); pos ++) {
     61        for (int pos = 0; pos < n; pos ++) {
    6162            newNodes[pos] = new ArrayList<Node>(ways.get(pos).getNodes());
    6263            wayBounds[pos] = getNodesBounds(newNodes[pos]);
    6364            changedWays[pos] = false;
     
    6566
    6667        //iterate over all way pairs and introduce the intersections
    6768        Comparator<Node> coordsComparator = new NodePositionComparator();
     69        WayLoop: for (int seg1Way = 0; seg1Way < n; seg1Way ++) {
     70            for (int seg2Way = seg1Way; seg2Way < n; seg2Way ++) {
    6871
    69         WayLoop: for (int seg1Way = 0; seg1Way < ways.size(); seg1Way ++) {
    70             for (int seg2Way = seg1Way; seg2Way < ways.size(); seg2Way ++) {
    71 
    7272                //do not waste time on bounds that do not intersect
    7373                if (!wayBounds[seg1Way].intersects(wayBounds[seg2Way])) {
    7474                    continue;
     
    127127                                Node intNode = newNode;
    128128                                boolean insertInSeg1 = false;
    129129                                boolean insertInSeg2 = false;
    130 
    131130                                //find if the intersection point is at end point of one of the segments, if so use that point
    132131
    133132                                //segment 1
     
    265264        //TODO: do this locally.
    266265        if (!Line2D.linesIntersect(x1, y1, x2, y2, x3, y3, x4, y4)) return null;
    267266
    268         // Convert line from (point, point) form to ax+by=c
    269         double a1 = y2 - y1;
    270         double b1 = x1 - x2;
    271         double c1 = x2*y1 - x1*y2;
     267        // solve line-line intersection in parametric form:
     268        // (x1,y1) + (x2-x1,y2-y1)* u  = (x3,y3) + (x4-x3,y4-y3)* v
     269        // (x2-x1,y2-y1)*u - (x4-x3,y4-y3)*v = (x3-x1,y3-y1)
     270        // if 0<= u,v <=1, intersection exists at ( x1+ (x2-x1)*u, y1 + (y2-y1)*u )
     271       
     272        double a1 = x2 - x1;
     273        double b1 = x3 - x4;
     274        double c1 = x3 - x1;
    272275
    273         double a2 = y4 - y3;
    274         double b2 = x3 - x4;
    275         double c2 = x4*y3 - x3*y4;
     276        double a2 = y2 - y1;
     277        double b2 = y3 - y4;
     278        double c2 = y3 - y1;
    276279
    277280        // Solve the equations
    278281        double det = a1*b2 - a2*b1;
    279         if (det == 0) return null; // Lines are parallel
    280 
    281         double x = (b1*c2 - b2*c1)/det;
    282         double y = (a2*c1 -a1*c2)/det;
    283 
    284         return new EastNorth(x, y);
     282       
     283        double uu = b2*c1 - b1*c2 ;
     284        double vv = a1*c2 - a2*c1;
     285        double mag = Math.abs(uu)+Math.abs(vv);
     286               
     287        if (Math.abs(det) > 1e-12 * mag) {
     288            double u = uu/det, v = vv/det;
     289            if (u>-1e-8 && u < 1+1e-8 && v>-1e-8 && v < 1+1e-8 ) {
     290                if (u<0) u=0;
     291                if (u>1) u=1.0;
     292                return new EastNorth(x1+a1*u, y1+a2*u);
     293            } else {
     294                return null;
     295            }
     296        } else {
     297            // parallel lines
     298            return null;
     299        }
    285300    }
    286301
    287302    /**