Ignore:
Timestamp:
2012-01-27T06:15:36+01:00 (13 years ago)
Author:
joshdoe
Message:

utilsplugin2: Replace geometry of node with multipolygon (fixes #7313)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/dumbutils/ReplaceGeometryAction.java

    r27624 r27645  
    1313import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1414import org.openstreetmap.josm.data.osm.Relation;
     15import org.openstreetmap.josm.data.osm.RelationMember;
    1516import org.openstreetmap.josm.data.osm.RelationToChildReference;
    1617import org.openstreetmap.josm.data.osm.TagCollection;
     
    5657        if (firstObject instanceof Way && secondObject instanceof Way) {
    5758            replaceWayWithWay(Arrays.asList((Way) firstObject, (Way) secondObject));
    58         } else if (firstObject instanceof Node && secondObject instanceof Way) {
    59             replaceNodeWithWay((Node) firstObject, (Way) secondObject);
    60         } else if (secondObject instanceof Node && firstObject instanceof Way) {
    61             replaceNodeWithWay((Node) secondObject, (Way) firstObject);
     59        } else if (firstObject instanceof Node && secondObject instanceof Node) {
     60            JOptionPane.showMessageDialog(Main.parent,
     61                    tr("To replace a node with a node, use the node merge tool."),
     62                    TITLE, JOptionPane.INFORMATION_MESSAGE);
     63            return;
     64        } else if (firstObject instanceof Node) {
     65            replaceNode((Node) firstObject, secondObject);
     66        } else if (secondObject instanceof Node) {
     67            replaceNode((Node) secondObject, firstObject);
    6268        } else {
    6369            JOptionPane.showMessageDialog(Main.parent,
    64                     tr("This tool can only replace a node with a way, or a way with a way."),
     70                    tr("This tool can only replace a node with a way, a node with a multipolygon, or a way with a way."),
    6571                    TITLE, JOptionPane.INFORMATION_MESSAGE);
    6672            return;
    6773        }
    6874    }
    69    
    70     public void replaceNodeWithWay(Node node, Way way) {
     75
     76    /**
     77     * Replace or upgrade a node to a way or multipolygon
     78     *
     79     * @param node
     80     * @param target
     81     */
     82    public void replaceNode(Node node, OsmPrimitive target) {
    7183        if (!node.getReferrers().isEmpty()) {
    72             JOptionPane.showMessageDialog(Main.parent, tr("Node has referrers, cannot replace with way."), TITLE, JOptionPane.INFORMATION_MESSAGE);
    73             return;
    74         }
     84            JOptionPane.showMessageDialog(Main.parent, tr("Node belongs to way(s) or relation(s), cannot replace."),
     85                    TITLE, JOptionPane.INFORMATION_MESSAGE);
     86            return;
     87        }
     88
     89        if (target instanceof Relation && !((Relation) target).isMultipolygon()) {
     90            JOptionPane.showMessageDialog(Main.parent, tr("Relation is not a multipolygon, cannot be used as a replacement."),
     91                    TITLE, JOptionPane.INFORMATION_MESSAGE);
     92            return;
     93        }
     94
    7595        Node nodeToReplace = null;
    7696        // see if we need to replace a node in the replacement way to preserve connection in history
    7797        if (!node.isNew()) {
    78             // Prepare a list of nodes that are not used anywhere except in the way
    79             Collection<Node> nodePool = getUnimportantNodes(way);
     98            // Prepare a list of nodes that are not important
     99            Collection<Node> nodePool = new HashSet<Node>();
     100            if (target instanceof Way) {
     101                nodePool.addAll(getUnimportantNodes((Way) target));
     102            } else if (target instanceof Relation) {
     103                for (RelationMember member : ((Relation) target).getMembers()) {
     104                    if ((member.getRole().equals("outer") || member.getRole().equals("inner"))
     105                            && member.isWay()) {
     106                        // TODO: could consider more nodes, such as nodes that are members of other ways,
     107                        // just need to replace occurences in all referrers
     108                        nodePool.addAll(getUnimportantNodes(member.getWay()));
     109                    }
     110                }
     111            } else {
     112                assert false;
     113            }
    80114            nodeToReplace = findNearestNode(node, nodePool);
    81115        }
     
    85119
    86120        // merge tags
    87         Collection<Command> tagResolutionCommands = getTagConflictResolutionCommands(node, way);
     121        Collection<Command> tagResolutionCommands = getTagConflictResolutionCommands(node, target);
    88122        if (tagResolutionCommands == null) {
    89123            // user canceled tag merge dialog
     
    91125        }
    92126        commands.addAll(tagResolutionCommands);
    93        
     127
    94128        // replace sacrificial node in way with node that is being upgraded
    95129        if (nodeToReplace != null) {
    96             List<Node> wayNodes = way.getNodes();
     130            // node should only have one parent, a way
     131            Way parentWay = (Way) nodeToReplace.getReferrers().get(0);
     132            List<Node> wayNodes = parentWay.getNodes();
    97133            int idx = wayNodes.indexOf(nodeToReplace);
    98134            wayNodes.set(idx, node);
    99             if (idx == 0 && way.isClosed()) {
     135            if (idx == 0 && parentWay.isClosed()) {
    100136                // node is at start/end of way
    101137                wayNodes.set(wayNodes.size() - 1, node);
    102138            }
    103             commands.add(new ChangeNodesCommand(way, wayNodes));
     139            commands.add(new ChangeNodesCommand(parentWay, wayNodes));
    104140            commands.add(new MoveCommand(node, nodeToReplace.getCoor()));
    105141            commands.add(new DeleteCommand(nodeToReplace));
     
    117153        }
    118154
    119         getCurrentDataSet().setSelected(way);
     155        getCurrentDataSet().setSelected(target);
    120156
    121157        Main.main.undoRedo.add(new SequenceCommand(
    122                 tr("Replace geometry for way {0}", way.getDisplayName(DefaultNameFormatter.getInstance())),
     158                tr("Replace geometry for node {0}", node.getDisplayName(DefaultNameFormatter.getInstance())),
    123159                commands));
    124160    }
Note: See TracChangeset for help on using the changeset viewer.