Ignore:
Timestamp:
2010-11-10T16:02:09+01:00 (14 years ago)
Author:
extropy
Message:

multipoly: removes tags/values from inner ways that are present in outer ways or in relation.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/multipoly/src/multipoly/MultipolyAction.java

    r23896 r24179  
    66import java.awt.event.ActionEvent;
    77import java.awt.event.KeyEvent;
     8import java.util.ArrayList;
    89import java.util.Collection;
    9 import java.util.Collections;
     10import java.util.HashMap;
     11import java.util.List;
     12import java.util.Map;
    1013
    1114import javax.swing.JOptionPane;
     
    1619import org.openstreetmap.josm.actions.JosmAction;
    1720import org.openstreetmap.josm.command.AddCommand;
     21import org.openstreetmap.josm.command.ChangePropertyCommand;
    1822import org.openstreetmap.josm.command.Command;
    1923import org.openstreetmap.josm.command.SequenceCommand;
     
    2327import org.openstreetmap.josm.data.osm.Way;
    2428import org.openstreetmap.josm.gui.dialogs.relation.RelationEditor;
    25 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    2629import org.openstreetmap.josm.tools.Shortcut;
    2730
     
    4346public class MultipolyAction extends JosmAction {
    4447
    45   public MultipolyAction() {
    46     super(tr("Create multipolygon"), "multipoly_create", tr("Create multipolygon."),
    47       Shortcut.registerShortcut("tools:multipoly", tr("Tool: {0}", tr("Create multipolygon")),
    48       KeyEvent.VK_M, Shortcut.GROUP_EDIT, Shortcut.SHIFT_DEFAULT), true);
    49   }
    50   /**
    51    * The action button has been clicked
    52    *
    53    * @param e Action Event
    54    */
    55   public void actionPerformed(ActionEvent e) {
    56     if (Main.main.getEditLayer() == null) {
    57       JOptionPane.showMessageDialog(Main.parent, tr("No data loaded."));
    58       return;
    59     }
    60 
    61     Collection < Way > selectedWays = Main.main.getCurrentDataSet().getSelectedWays();
    62 
    63     if (selectedWays.size() < 1) {
    64       // Sometimes it make sense creating multipoly of only one way (so it will form outer way)
    65       // and then splitting the way later (so there are multiple ways forming outer way)
    66       JOptionPane.showMessageDialog(Main.parent, tr("You must select at least one way."));
    67       return;
    68     }
    69 
    70     Multipolygon polygon = this.analyzeWays(selectedWays);
    71 
    72     if (polygon == null) {
    73       return;                   //could not make multipolygon.
    74     }
    75 
    76     Relation relation = this.createRelation(polygon);
    77 
    78     if (Main.pref.getBoolean("multipoly.show-relation-editor", false)) {
    79       //Open relation edit window, if set up in preferences
    80       RelationEditor editor = RelationEditor.getEditor(Main.main.getEditLayer(), relation, null);
    81       editor.setVisible(true);
    82     } else {
    83       //Just add the relation
    84       Main.main.undoRedo.add(new AddCommand(relation));
    85       Main.map.repaint();
    86     }
    87   }
    88 
    89   /** Enable this action only if something is selected */
    90   @Override protected void updateEnabledState() {
    91     if (getCurrentDataSet() == null) {
    92       setEnabled(false);
    93     } else {
    94       updateEnabledState(getCurrentDataSet().getSelected());
    95     }
    96   }
    97 
    98   /** Enable this action only if something is selected */
    99   @Override protected void updateEnabledState(Collection < ? extends OsmPrimitive > selection) {
    100     setEnabled(selection != null && !selection.isEmpty());
    101   }
    102 
    103   /**
    104    * This method analyzes ways and creates multipolygon.
    105    * @param selectedWays
    106    * @return null, if there was a problem with the ways.
    107    */
    108   private Multipolygon analyzeWays(Collection < Way > selectedWays) {
    109 
    110     Multipolygon pol = new Multipolygon();
    111     String error = pol.makeFromWays(selectedWays);
    112 
    113     if (error != null) {
    114       JOptionPane.showMessageDialog(Main.parent, error);
    115       return null;
    116     } else {
    117       return pol;
    118     }
    119   }
    120 
    121   /**
    122    * Builds a relation from polygon ways.
    123    * @param pol
    124    * @return
    125    */
    126   private Relation createRelation(Multipolygon pol) {
    127     // Create new relation
    128     Relation rel = new Relation();
    129     rel.put("type", "multipolygon");
    130     // Add ways to it
    131     for (JoinedPolygon jway:pol.outerWays) {
    132       for (Way way:jway.ways) {
    133           rel.addMember(new RelationMember("outer", way));
    134       }
    135     }
    136 
    137     for (JoinedPolygon jway:pol.innerWays) {
    138       for (Way way:jway.ways) {
    139           rel.addMember(new RelationMember("inner", way));
    140       }
    141     }
    142     return rel;
    143   }
     48        public MultipolyAction() {
     49                super(tr("Create multipolygon"), "multipoly_create", tr("Create multipolygon."),
     50                                Shortcut.registerShortcut("tools:multipoly", tr("Tool: {0}", tr("Create multipolygon")),
     51                                                KeyEvent.VK_M, Shortcut.GROUP_EDIT, Shortcut.SHIFT_DEFAULT), true);
     52        }
     53        /**
     54         * The action button has been clicked
     55         *
     56         * @param e Action Event
     57         */
     58        public void actionPerformed(ActionEvent e) {
     59                if (Main.main.getEditLayer() == null) {
     60                        JOptionPane.showMessageDialog(Main.parent, tr("No data loaded."));
     61                        return;
     62                }
     63
     64                Collection < Way > selectedWays = Main.main.getCurrentDataSet().getSelectedWays();
     65
     66                if (selectedWays.size() < 1) {
     67                        // Sometimes it make sense creating multipoly of only one way (so it will form outer way)
     68                        // and then splitting the way later (so there are multiple ways forming outer way)
     69                        JOptionPane.showMessageDialog(Main.parent, tr("You must select at least one way."));
     70                        return;
     71                }
     72
     73                Multipolygon polygon = this.analyzeWays(selectedWays);
     74
     75                if (polygon == null) {
     76                        return;                   //could not make multipolygon.
     77                }
     78
     79                Relation relation = this.createRelation(polygon);
     80
     81                if (Main.pref.getBoolean("multipoly.show-relation-editor", false)) {
     82                        //Open relation edit window, if set up in preferences
     83                        RelationEditor editor = RelationEditor.getEditor(Main.main.getEditLayer(), relation, null);
     84
     85                        editor.setModal(true);
     86                        editor.setVisible(true);
     87
     88                        //TODO: cannot get the resulting relation from RelationEditor :(.
     89                        /*
     90                        if (relationCountBefore < relationCountAfter) {
     91                                //relation saved, clean up the tags
     92                                List<Command> list = this.removeTagsFromInnerWays(relation);
     93                                if (list.size() > 0)
     94                                {
     95                                        Main.main.undoRedo.add(new SequenceCommand(tr("Remove tags from multipolygon inner ways"), list));
     96                                }
     97                        }
     98                         */
     99
     100                } else {
     101                        //Just add the relation
     102                        List<Command> list = this.removeTagsFromInnerWays(relation);
     103                        list.add(new AddCommand(relation));
     104                        Main.main.undoRedo.add(new SequenceCommand(tr("Create multipolygon"), list));
     105                        Main.map.repaint();
     106                }
     107
     108
     109        }
     110
     111        /** Enable this action only if something is selected */
     112        @Override protected void updateEnabledState() {
     113                if (getCurrentDataSet() == null) {
     114                        setEnabled(false);
     115                } else {
     116                        updateEnabledState(getCurrentDataSet().getSelected());
     117                }
     118        }
     119
     120        /** Enable this action only if something is selected */
     121        @Override protected void updateEnabledState(Collection < ? extends OsmPrimitive > selection) {
     122                setEnabled(selection != null && !selection.isEmpty());
     123        }
     124
     125        /**
     126         * This method analyzes ways and creates multipolygon.
     127         * @param selectedWays
     128         * @return null, if there was a problem with the ways.
     129         */
     130        private Multipolygon analyzeWays(Collection < Way > selectedWays) {
     131
     132                Multipolygon pol = new Multipolygon();
     133                String error = pol.makeFromWays(selectedWays);
     134
     135                if (error != null) {
     136                        JOptionPane.showMessageDialog(Main.parent, error);
     137                        return null;
     138                } else {
     139                        return pol;
     140                }
     141        }
     142
     143        /**
     144         * Builds a relation from polygon ways.
     145         * @param pol
     146         * @return
     147         */
     148        private Relation createRelation(Multipolygon pol) {
     149                // Create new relation
     150                Relation rel = new Relation();
     151                rel.put("type", "multipolygon");
     152                // Add ways to it
     153                for (JoinedPolygon jway:pol.outerWays) {
     154                        for (Way way:jway.ways) {
     155                                rel.addMember(new RelationMember("outer", way));
     156                        }
     157                }
     158
     159                for (JoinedPolygon jway:pol.innerWays) {
     160                        for (Way way:jway.ways) {
     161                                rel.addMember(new RelationMember("inner", way));
     162                        }
     163                }
     164                return rel;
     165        }
     166
     167
     168        /**
     169         * This method removes tags/value pairs from inner ways that are present in relation or outer ways.
     170         * @param relation
     171         */
     172        private List<Command> removeTagsFromInnerWays(Relation relation) {
     173                Map<String, String> values = new HashMap<String, String>();
     174
     175                if (relation.hasKeys()){
     176                        for(String key: relation.keySet()) {
     177                                values.put(key, relation.get(key));
     178                        }
     179                }
     180
     181                List<Way> innerWays = new ArrayList<Way>();
     182
     183                for(RelationMember m: relation.getMembers()) {
     184
     185                        if (m.hasRole() && m.getRole() == "inner" && m.isWay() && m.getWay().hasKeys()) {
     186                                innerWays.add(m.getWay());
     187                        }
     188
     189                        if (m.hasRole() && m.getRole() == "outer" && m.isWay() && m.getWay().hasKeys()) {
     190                                Way way = m.getWay();
     191                                for (String key: way.keySet()) {
     192                                        if (!values.containsKey(key)) { //relation values take precedence
     193                                                values.put(key, way.get(key));
     194                                        }
     195                                }
     196                        }
     197                }
     198
     199                List<Command> commands = new ArrayList<Command>();
     200
     201                for(String key: values.keySet()) {
     202                        List<OsmPrimitive> affectedWays = new ArrayList<OsmPrimitive>();
     203                        String value = values.get(key);
     204
     205                        for(Way way: innerWays){
     206                                if (value.equals(way.get(key))) {
     207                                        affectedWays.add(way);
     208                                }
     209                        }
     210
     211                        if (affectedWays.size() > 0) {
     212                                commands.add(new ChangePropertyCommand(affectedWays, key, null));
     213                        }
     214                }
     215
     216                return commands;
     217        }
    144218}
Note: See TracChangeset for help on using the changeset viewer.