Ticket #16948: 16948_buildings-v2.patch

File 16948_buildings-v2.patch, 3.6 KB (added by GerdP, 8 years ago)
  • src/org/openstreetmap/josm/plugins/buildings_tools/Building.java

     
    99import java.awt.Point;
    1010import java.awt.geom.GeneralPath;
    1111import java.util.ArrayList;
     12import java.util.Arrays;
    1213import java.util.Collection;
    1314import java.util.Collections;
    1415import java.util.LinkedList;
     
    3637import org.openstreetmap.josm.data.osm.Way;
    3738import org.openstreetmap.josm.gui.MainApplication;
    3839import org.openstreetmap.josm.gui.MapView;
     40import org.openstreetmap.josm.tools.Geometry;
    3941
    4042class Building {
    4143    private final EastNorth[] en = new EastNorth[4];
     
    396398
    397399        addAddress(w);
    398400
     401        // calculate BBox which is slightly larger than the new building
     402        BBox searchBox = new BBox();
     403        final double maxDist = 0.001;
     404        List<Node> wayNodes = w.getNodes();
     405        for (Node n : nodes) {
     406            LatLon l = eastNorth2latlon(n.getEastNorth());
     407            searchBox.add(new BBox(l.lon() - 0.0000001, l.lat() - 0.0000001,
     408                    l.lon() + 0.0000001, l.lat() + 0.0000001));
     409        }
     410        // find the ways which might be snapped to the new building
     411        List<Way> others = ds.searchWays(searchBox);
     412        // add nodes of existing buildings to the new one
     413        for (Way other : others) {
     414            if (other.get("building") == null)
     415                continue;
     416            snapToWay(wayNodes, other.getNodes(), maxDist);
     417            w.setNodes(wayNodes);
     418        }
     419        // add new nodes to existing buildings
     420        for (Way other : others) {
     421            if (other.get("building") == null)
     422                continue;
     423            List<Node> otherNodes = other.getNodes();
     424            snapToWay(otherNodes, Arrays.asList(nodes), maxDist);
     425            if (otherNodes.size() != other.getNodesCount()) {
     426                Way newWay = new Way(other);
     427                newWay.setNodes(otherNodes);
     428                cmds.add(new ChangeCommand(other, newWay));
     429            }
     430        }
     431
    399432        Command c = new SequenceCommand(tr("Create building"), cmds);
    400433        UndoRedoHandler.getInstance().add(c);
    401434        return w;
    402435    }
    403436
     437    /**
     438     * Add all nodes in otherNodes to wayNodes that are within maxDist to the
     439     * segments described by wayNodes
     440     *
     441     * @param wayNodes
     442     *            List of nodes that might be changed
     443     * @param otherNodes
     444     *            other nodes
     445     * @param maxDist
     446     *            maximum Distance in
     447     */
     448    private static void snapToWay(List<Node> wayNodes, Collection<Node> otherNodes, double maxDist) {
     449        for (int i = 0; i < wayNodes.size(); i++) {
     450            Node n0 = wayNodes.get(i);
     451            Node n1 = wayNodes.get(i + 1 == wayNodes.size() ? 0 : i + 1);
     452            for (Node n2 : otherNodes) {
     453                if (n2 == n0 || n2 == n1)
     454                    continue;
     455                EastNorth x = Geometry.closestPointToSegment(n0.getEastNorth(), n1.getEastNorth(),
     456                        n2.getEastNorth());
     457                if (x.distanceSq(n2.getEastNorth()) < maxDist) {
     458                    wayNodes.add(i + 1, n2);
     459                    i--; // we may add multiple nodes to one segment, so repeat
     460                         // it
     461                    break;
     462                }
     463            }
     464        }
     465    }
     466
    404467    private void addAddress(Way w) {
    405468        if (ToolSettings.PROP_USE_ADDR_NODE.get()) {
    406469            Node addrNode = getAddressNode();