Ignore:
Timestamp:
2009-09-30T20:00:57+02:00 (15 years ago)
Author:
Gubaer
Message:

fixed #3556: False positive conflicts when merging nodes
fixed #3460: show only conflicting tags at conflict resolution dialog
fixed #3103: resolve conflicts after combining just one conflict

Location:
trunk/src/org/openstreetmap/josm/actions
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/CombineWayAction.java

    r2210 r2220  
    22package org.openstreetmap.josm.actions;
    33
     4import static org.openstreetmap.josm.gui.conflict.tags.TagConflictResolutionUtil.combineTigerTags;
     5import static org.openstreetmap.josm.gui.conflict.tags.TagConflictResolutionUtil.completeTagCollectionForEditing;
     6import static org.openstreetmap.josm.gui.conflict.tags.TagConflictResolutionUtil.normalizeTagCollectionBeforeEditing;
    47import static org.openstreetmap.josm.tools.I18n.tr;
    58
     
    3033import org.openstreetmap.josm.data.osm.Relation;
    3134import org.openstreetmap.josm.data.osm.RelationMember;
    32 import org.openstreetmap.josm.data.osm.Tag;
    3335import org.openstreetmap.josm.data.osm.TagCollection;
    34 import org.openstreetmap.josm.data.osm.TigerUtils;
    3536import org.openstreetmap.josm.data.osm.Way;
    3637import org.openstreetmap.josm.gui.ExtendedDialog;
     
    3839import org.openstreetmap.josm.tools.Pair;
    3940import org.openstreetmap.josm.tools.Shortcut;
    40 
    4141/**
    4242 * Combines multiple ways into one.
     
    8888    }
    8989
    90     protected static void completeTagCollectionWithMissingTags(TagCollection tc, Collection<? extends OsmPrimitive> merged) {
    91         for (String key: tc.getKeys()) {
    92             // make sure the empty value is in the tag set if a tag is not present
    93             // on all merged nodes
    94             //
    95             for (OsmPrimitive p: merged) {
    96                 if (p.get(key) == null) {
    97                     tc.add(new Tag(key)); // add a tag with key and empty value
    98                 }
    99             }
    100         }
    101         // remove irrelevant tags
    102         //
    103         tc.removeByKey("created_by");
    104     }
    105 
    106     /**
    107      * Combines tags from TIGER data
    108      *
    109      * @param tc the tag collection
    110      */
    111     protected static void combineTigerTags(TagCollection tc) {
    112         for (String key: tc.getKeys()) {
    113             if (TigerUtils.isTigerTag(key)) {
    114                 tc.setUniqueForKey(key, TigerUtils.combineTags(key, tc.getValues(key)));
    115             }
    116         }
    117     }
    118 
    119     protected static void completeTagCollectionForEditing(TagCollection tc) {
    120         for (String key: tc.getKeys()) {
    121             // make sure the empty value is in the tag set such that we can delete the tag
    122             // in the conflict dialog if necessary
    123             //
    124             tc.add(new Tag(key,""));
    125         }
    126     }
    12790
    12891    public void combineWays(Collection<Way> ways) {
     
    170133        TagCollection completeWayTags = new TagCollection(wayTags);
    171134        combineTigerTags(completeWayTags);
    172         completeTagCollectionWithMissingTags(completeWayTags, ways);
     135        normalizeTagCollectionBeforeEditing(completeWayTags, ways);
    173136        TagCollection tagsToEdit = new TagCollection(completeWayTags);
    174137        completeTagCollectionForEditing(tagsToEdit);
    175138
    176139        CombinePrimitiveResolverDialog dialog = CombinePrimitiveResolverDialog.getInstance();
    177         dialog.getTagConflictResolverModel().populate(tagsToEdit);
     140        dialog.getTagConflictResolverModel().populate(tagsToEdit, completeWayTags.getKeysWithMultipleValues());
    178141        dialog.setTargetPrimitive(targetWay);
    179142        dialog.getRelationMemberConflictResolverModel().populate(
  • trunk/src/org/openstreetmap/josm/actions/MergeNodesAction.java

    r2202 r2220  
    22package org.openstreetmap.josm.actions;
    33
     4import static org.openstreetmap.josm.gui.conflict.tags.TagConflictResolutionUtil.combineTigerTags;
     5import static org.openstreetmap.josm.gui.conflict.tags.TagConflictResolutionUtil.completeTagCollectionForEditing;
     6import static org.openstreetmap.josm.gui.conflict.tags.TagConflictResolutionUtil.normalizeTagCollectionBeforeEditing;
    47import static org.openstreetmap.josm.tools.I18n.tr;
    58
     
    2326import org.openstreetmap.josm.data.osm.Node;
    2427import org.openstreetmap.josm.data.osm.OsmPrimitive;
    25 import org.openstreetmap.josm.data.osm.Tag;
    2628import org.openstreetmap.josm.data.osm.TagCollection;
    27 import org.openstreetmap.josm.data.osm.TigerUtils;
    2829import org.openstreetmap.josm.data.osm.Way;
    2930import org.openstreetmap.josm.data.osm.BackreferencedDataSet.RelationToChildReference;
     
    5960        }
    6061
    61 
    6262        Node targetNode = selectTargetNode(selectedNodes);
    6363        Command cmd = mergeNodes(Main.main.getEditLayer(), selectedNodes, targetNode);
     
    6565            Main.main.undoRedo.add(cmd);
    6666            Main.main.getEditLayer().data.setSelected(targetNode);
    67         }
    68     }
    69 
    70     protected static void completeTagCollectionWithMissingTags(TagCollection tc, Collection<Node> mergedNodes) {
    71         for (String key: tc.getKeys()) {
    72             // make sure the empty value is in the tag set if a tag is not present
    73             // on all merged nodes
    74             //
    75             for (Node n: mergedNodes) {
    76                 if (n.get(key) == null) {
    77                     tc.add(new Tag(key)); // add a tag with key and empty value
    78                 }
    79             }
    80         }
    81         // remove irrelevant tags
    82         //
    83         tc.removeByKey("created_by");
    84     }
    85 
    86     protected static void completeTagCollectionForEditing(TagCollection tc) {
    87         for (String key: tc.getKeys()) {
    88             // make sure the empty value is in the tag set such that we can delete the tag
    89             // in the conflict dialog if necessary
    90             //
    91             tc.add(new Tag(key,""));
    92         }
    93     }
    94 
    95     /**
    96      * Combines tags from TIGER data
    97      *
    98      * @param tc the tag collection
    99      */
    100     protected static void combineTigerTags(TagCollection tc) {
    101         for (String key: tc.getKeys()) {
    102             if (TigerUtils.isTigerTag(key)) {
    103                 tc.setUniqueForKey(key, TigerUtils.combineTags(key, tc.getValues(key)));
    104             }
    10567        }
    10668    }
     
    220182
    221183    /**
    222      * Merges the nodes in <code>node</code> onto one of the nodes. Uses the dataset
     184     * Merges the nodes in <code>nodes</code> onto one of the nodes. Uses the dataset
    223185     * managed by <code>layer</code> as reference. <code>backreferences</code> is a precomputed
    224186     * collection of all parent/child references in the dataset.
     
    250212        TagCollection nodeTags = TagCollection.unionOfAllPrimitives(nodes);
    251213        combineTigerTags(nodeTags);
    252         completeTagCollectionWithMissingTags(nodeTags, nodes);
     214        normalizeTagCollectionBeforeEditing(nodeTags, nodes);
    253215        TagCollection nodeTagsToEdit = new TagCollection(nodeTags);
    254216        completeTagCollectionForEditing(nodeTagsToEdit);
     
    257219        //
    258220        CombinePrimitiveResolverDialog dialog = CombinePrimitiveResolverDialog.getInstance();
    259         dialog.getTagConflictResolverModel().populate(nodeTagsToEdit);
     221        dialog.getTagConflictResolverModel().populate(nodeTagsToEdit, nodeTags.getKeysWithMultipleValues());
    260222        dialog.getRelationMemberConflictResolverModel().populate(relationToNodeReferences);
    261223        dialog.setTargetPrimitive(targetNode);
    262224        dialog.prepareDefaultDecisions();
     225        // conflict resolution is necessary if there are conflicts in the merged tags
     226        // or if at least one of the merged nodes is referred to by a relation
     227        //
    263228        if (! nodeTags.isApplicableToPrimitive() || relationToNodeReferences.size() > 1) {
    264229            dialog.setVisible(true);
     
    283248        if (wayFixCommands == null)
    284249            return null;
    285         else {
    286             cmds.addAll(wayFixCommands);
    287         }
     250        cmds.addAll(wayFixCommands);
    288251
    289252        // build the commands
     
    299262        return cmd;
    300263    }
    301 
    302264
    303265    /**
  • trunk/src/org/openstreetmap/josm/actions/PasteTagsAction.java

    r2070 r2220  
    3838
    3939    static private List<Class<? extends OsmPrimitive>> osmPrimitiveClasses;
    40     {
     40    static {
    4141        osmPrimitiveClasses = new ArrayList<Class<? extends OsmPrimitive>>();
    4242        osmPrimitiveClasses.add(Node.class);
     
    6060
    6161    /**
    62      * Replies the subset  of {@see OsmPrimitive}s of <code>type</code> from <code>superSet</code>.
    63      *
    64      * @param <T>
    65      * @param superSet  the super set of primitives
    66      * @param type  the type
    67      * @return
    68      */
    69     protected <T extends OsmPrimitive> Collection<? extends OsmPrimitive> getSubcollectionByType(Collection<? extends OsmPrimitive> superSet, Class<T> type) {
    70         Collection<OsmPrimitive> ret = new ArrayList<OsmPrimitive>();
    71         for (OsmPrimitive p : superSet) {
    72             if (type.isInstance(p)) {
    73                 ret.add(p);
    74             }
    75         }
    76         return ret;
    77     }
    78 
    79     /**
    8062     * Replies all primitives of type <code>type</code> in the current selection.
    8163     *
     
    8567     */
    8668    protected <T extends OsmPrimitive> Collection<? extends OsmPrimitive> getSourcePrimitivesByType(Class<T> type) {
    87         return getSubcollectionByType(Main.pasteBuffer.getSelected(), type);
     69        return OsmPrimitive.getFilteredList(Main.pasteBuffer.getSelected(), type);
    8870    }
    8971
     
    145127        HashMap<OsmPrimitiveType, Integer> ret = new HashMap<OsmPrimitiveType, Integer>();
    146128        for (Class<? extends OsmPrimitive> type: osmPrimitiveClasses) {
    147             int count = getSubcollectionByType(getEditLayer().data.getSelected(), type).size();
     129            int count = OsmPrimitive.getFilteredList(getEditLayer().data.getSelected(), type).size();
    148130            if (count > 0) {
    149131                ret.put(OsmPrimitiveType.from(type), count);
     
    173155            // no tags found to paste. Abort.
    174156            return;
    175 
    176157
    177158        if (!tc.isApplicableToPrimitive()) {
     
    202183     * <code>selection</code>
    203184     */
    204     protected <T extends OsmPrimitive> boolean hasTargetPrimitives(Collection<? extends OsmPrimitive> selection, Class<T> type) {
    205         return !getSubcollectionByType(selection, type).isEmpty();
     185    protected <T extends OsmPrimitive> boolean hasTargetPrimitives(Collection<OsmPrimitive> selection, Class<T> type) {
     186        return !OsmPrimitive.getFilteredList(selection, type).isEmpty();
    206187    }
    207188
     
    212193     * @return true if this a heterogeneous source can be pasted without conflicts to targets
    213194     */
    214     protected boolean canPasteFromHeterogeneousSourceWithoutConflict(Collection<? extends OsmPrimitive> targets) {
     195    protected boolean canPasteFromHeterogeneousSourceWithoutConflict(Collection<OsmPrimitive> targets) {
    215196        if (hasTargetPrimitives(targets, Node.class)) {
    216197            TagCollection tc = TagCollection.unionOfAllPrimitives(getSourcePrimitivesByType(Node.class));
     
    237218     * @param targets the collection of target primitives
    238219     */
    239     protected void pasteFromHeterogeneousSource(Collection<? extends OsmPrimitive> targets) {
     220    protected void pasteFromHeterogeneousSource(Collection<OsmPrimitive> targets) {
    240221        if (canPasteFromHeterogeneousSourceWithoutConflict(targets)) {
    241222            if (hasSourceTagsByType(Node.class) && hasTargetPrimitives(targets, Node.class)) {
     
    264245                return;
    265246            if (hasSourceTagsByType(Node.class) && hasTargetPrimitives(targets, Node.class)) {
    266                 Command cmd = buildChangeCommand(getSubcollectionByType(targets, Node.class), dialog.getResolution(OsmPrimitiveType.NODE));
     247                Command cmd = buildChangeCommand(OsmPrimitive.getFilteredList(targets, Node.class), dialog.getResolution(OsmPrimitiveType.NODE));
    267248                Main.main.undoRedo.add(cmd);
    268249            }
    269250            if (hasSourceTagsByType(Way.class) && hasTargetPrimitives(targets, Way.class)) {
    270                 Command cmd = buildChangeCommand(getSubcollectionByType(targets, Way.class), dialog.getResolution(OsmPrimitiveType.WAY));
     251                Command cmd = buildChangeCommand(OsmPrimitive.getFilteredList(targets, Way.class), dialog.getResolution(OsmPrimitiveType.WAY));
    271252                Main.main.undoRedo.add(cmd);
    272253            }
    273254            if (hasSourceTagsByType(Relation.class) && hasTargetPrimitives(targets, Relation.class)) {
    274                 Command cmd = buildChangeCommand(getSubcollectionByType(targets, Relation.class), dialog.getResolution(OsmPrimitiveType.RELATION));
     255                Command cmd = buildChangeCommand(OsmPrimitive.getFilteredList(targets, Relation.class), dialog.getResolution(OsmPrimitiveType.RELATION));
    275256                Main.main.undoRedo.add(cmd);
    276257            }
Note: See TracChangeset for help on using the changeset viewer.