Ignore:
Timestamp:
2012-05-09T16:06:02+02:00 (12 years ago)
Author:
akks
Message:

see #7458 : enable tags moving when creating multipolygon [improved code from Zverik's Relation Toolbox plugin copied back to core ]

File:
1 edited

Legend:

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

    r4982 r5225  
    77import java.awt.event.KeyEvent;
    88import java.util.ArrayList;
     9import java.util.Arrays;
    910import java.util.Collection;
    1011import java.util.HashMap;
     
    1213import java.util.Map;
    1314
     15import java.util.Set;
     16import java.util.TreeSet;
    1417import javax.swing.JOptionPane;
    1518
     
    1720import org.openstreetmap.josm.Main;
    1821import org.openstreetmap.josm.command.AddCommand;
     22import org.openstreetmap.josm.command.ChangeCommand;
    1923import org.openstreetmap.josm.command.ChangePropertyCommand;
    2024import org.openstreetmap.josm.command.Command;
     
    99103        } else {
    100104            //Just add the relation
    101             List<Command> list = this.removeTagsFromInnerWays(relation);
     105            List<Command> list = this.removeTagsFromWaysIfNeeded(relation);
    102106            list.add(new AddCommand(relation));
    103107            Main.main.undoRedo.add(new SequenceCommand(tr("Create multipolygon"), list));
     
    173177    }
    174178
    175     /**
    176      * This method removes tags/value pairs from inner ways that are present in relation or outer ways.
     179    static public final List<String> DEFAULT_LINEAR_TAGS = Arrays.asList(new String[] {"barrier", "source"});
     180
     181    /**
     182     * This method removes tags/value pairs from inner and outer ways and put them on relation if necessary
     183     * Function was extended in reltoolbox plugin by Zverikk and copied back to the core
    177184     * @param relation
    178185     */
    179     private List<Command> removeTagsFromInnerWays(Relation relation) {
    180         Map<String, String> values = new HashMap<String, String>();
    181 
    182         if (relation.hasKeys()){
    183             for(String key: relation.keySet()) {
    184                 values.put(key, relation.get(key));
    185             }
    186         }
    187 
    188         List<Way> innerWays = new ArrayList<Way>();
    189 
    190         for (RelationMember m: relation.getMembers()) {
    191 
    192             if (m.hasRole() && m.getRole() == "inner" && m.isWay() && m.getWay().hasKeys()) {
    193                 innerWays.add(m.getWay());
    194             }
    195 
    196             if (m.hasRole() && m.getRole() == "outer" && m.isWay() && m.getWay().hasKeys()) {
    197                 Way way = m.getWay();
    198                 for (String key: way.keySet()) {
    199                     if (!values.containsKey(key)) { //relation values take precedence
    200                         values.put(key, way.get(key));
    201                     }
    202                 }
    203             }
    204         }
    205 
    206         List<Command> commands = new ArrayList<Command>();
    207 
    208         for(String key: values.keySet()) {
    209             List<OsmPrimitive> affectedWays = new ArrayList<OsmPrimitive>();
    210             String value = values.get(key);
    211 
    212             for (Way way: innerWays) {
    213                 if (value.equals(way.get(key))) {
    214                     affectedWays.add(way);
    215                 }
    216             }
    217 
    218             if (affectedWays.size() > 0) {
    219                 commands.add(new ChangePropertyCommand(affectedWays, key, null));
    220             }
    221         }
    222 
    223         return commands;
     186    private List<Command> removeTagsFromWaysIfNeeded( Relation relation ) {
     187        Map<String, String> values = new HashMap<String, String>();
     188
     189        if( relation.hasKeys() ) {
     190            for( String key : relation.keySet() ) {
     191                values.put(key, relation.get(key));
     192            }
     193        }
     194
     195        List<Way> innerWays = new ArrayList<Way>();
     196        List<Way> outerWays = new ArrayList<Way>();
     197
     198        Set<String> conflictingKeys = new TreeSet<String>();
     199
     200        for( RelationMember m : relation.getMembers() ) {
     201
     202            if( m.hasRole() && "inner".equals(m.getRole()) && m.isWay() && m.getWay().hasKeys() ) {
     203                innerWays.add(m.getWay());
     204            }
     205
     206            if( m.hasRole() && "outer".equals(m.getRole()) && m.isWay() && m.getWay().hasKeys() ) {
     207                Way way = m.getWay();
     208                outerWays.add(way);
     209               
     210                for( String key : way.keySet() ) {
     211                    if( !values.containsKey(key) ) { //relation values take precedence
     212                        values.put(key, way.get(key));
     213                    } else if( !relation.hasKey(key) && !values.get(key).equals(way.get(key)) ) {
     214                        conflictingKeys.add(key);
     215                    }
     216                }
     217            }
     218        }
     219
     220        // filter out empty key conflicts - we need second iteration
     221        if( !Main.pref.getBoolean("multipoly.alltags", false) )
     222            for( RelationMember m : relation.getMembers() )
     223                if( m.hasRole() && m.getRole().equals("outer") && m.isWay() )
     224                    for( String key : values.keySet() )
     225                        if( !m.getWay().hasKey(key) && !relation.hasKey(key) )
     226                            conflictingKeys.add(key);
     227
     228        for( String key : conflictingKeys )
     229            values.remove(key);
     230
     231        for( String linearTag : Main.pref.getCollection("multipoly.lineartagstokeep", DEFAULT_LINEAR_TAGS) )
     232            values.remove(linearTag);
     233
     234        if( values.containsKey("natural") && values.get("natural").equals("coastline") )
     235            values.remove("natural");
     236
     237        values.put("area", "yes");
     238
     239        List<Command> commands = new ArrayList<Command>();
     240        boolean moveTags = Main.pref.getBoolean("multipoly.movetags", true);
     241
     242        for( String key : values.keySet() ) {
     243            List<OsmPrimitive> affectedWays = new ArrayList<OsmPrimitive>();
     244            String value = values.get(key);
     245
     246            for( Way way : innerWays ) {
     247                if( way.hasKey(key) && (value.equals(way.get(key))) ) {
     248                    affectedWays.add(way);
     249                }
     250            }
     251
     252            if( moveTags ) {
     253                // remove duplicated tags from outer ways
     254                for( Way way : outerWays ) {
     255                    if( way.hasKey(key) ) {
     256                        affectedWays.add(way);
     257                    }
     258                }
     259            }
     260
     261            if( affectedWays.size() > 0 ) {
     262                // reset key tag on affected ways
     263                commands.add(new ChangePropertyCommand(affectedWays, key, null));
     264            }
     265        }
     266
     267        if( moveTags ) {
     268            // add those tag values to the relation
     269
     270            boolean fixed = false;
     271            Relation r2 = new Relation(relation);
     272            for( String key : values.keySet() ) {
     273                if( !r2.hasKey(key) && !key.equals("area") ) {
     274                    if( relation.isNew() )
     275                        relation.put(key, values.get(key));
     276                    else
     277                        r2.put(key, values.get(key));
     278                    fixed = true;
     279                }
     280            }
     281            if( fixed && !relation.isNew() )
     282                commands.add(new ChangeCommand(relation, r2));
     283        }
     284
     285        return commands;
    224286    }
    225287}
Note: See TracChangeset for help on using the changeset viewer.