Changeset 5225 in josm


Ignore:
Timestamp:
May 9, 2012 4:06:02 PM (13 months 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.