Ignore:
Timestamp:
2011-03-24T19:39:23+01:00 (14 years ago)
Author:
zverik
Message:

new icon, major update for multipolygons, preferences, tuning (relcontext plugin)

Location:
applications/editors/josm/plugins/relcontext/src/relcontext
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/relcontext/src/relcontext/ChosenRelation.java

    r25680 r25692  
    8888        // todo: dim chosen relation when changing layer
    8989        // todo: check this WTF!
    90         if( newLayer != null ) {
     90        clear();
     91        if( newLayer != null && oldLayer == null ) {
    9192            Main.map.mapView.addTemporaryLayer(this);
    92         } else {
     93        } else if( oldLayer != null ) {
    9394            Main.map.mapView.removeTemporaryLayer(this);
    9495        }
  • applications/editors/josm/plugins/relcontext/src/relcontext/RelContextDialog.java

    r25688 r25692  
    11package relcontext;
    22
     3import java.io.IOException;
     4import java.io.BufferedReader;
     5import java.io.InputStream;
     6import java.io.Reader;
     7import java.io.InputStreamReader;
     8import java.awt.Point;
    39import java.awt.Component;
    410import java.awt.Dimension;
     
    5056public class RelContextDialog extends ToggleDialog implements EditLayerChangeListener, ChosenRelationListener, SelectionChangedListener {
    5157
     58    public final static String PREF_PREFIX = "reltoolbox";
     59    private static final String PREF_ROLEBOX = PREF_PREFIX + ".rolebox";
     60
    5261    private final DefaultTableModel relationsData;
    5362    private ChosenRelation chosenRelation;
    5463    private JPanel chosenRelationPanel;
    5564    private ChosenRelationPopupMenu popupMenu;
     65    private MultipolygonSettingsPopup multiPopupMenu;
    5666    private JLabel crRoleIndicator;
    5767    private AutoCompletingComboBox roleBox;
     
    5969
    6070    public RelContextDialog() {
    61         super(tr("Relation Toolbox"), "reltoolbox",
     71        super(tr("Relation Toolbox"), PREF_PREFIX,
    6272                tr("Open relation/multipolygon editor panel"),
    6373                Shortcut.registerShortcut("subwindow:reltoolbox", tr("Toggle: {0}", tr("Relation Toolbox")),
    6474                KeyEvent.VK_R, Shortcut.GROUP_LAYER, Shortcut.SHIFT_DEFAULT), 150, true);
    6575
    66         JPanel rcPanel = new JPanel(new BorderLayout());
    67 
    6876        chosenRelation = new ChosenRelation();
    6977        chosenRelation.addChosenRelationListener(this);
    7078        MapView.addEditLayerChangeListener(chosenRelation);
     79
     80        popupMenu = new ChosenRelationPopupMenu();
     81        multiPopupMenu = new MultipolygonSettingsPopup();
     82
     83        JPanel rcPanel = new JPanel(new BorderLayout());
    7184
    7285        relationsData = new RelationTableModel();
     
    127140            @Override
    128141            public void componentHidden( ComponentEvent e ) {
     142                Main.pref.put(PREF_ROLEBOX + ".visible", false);
    129143                toggleRolePanelButtonTop.setVisible(true);
    130144            }
     
    132146            @Override
    133147            public void componentShown( ComponentEvent e ) {
     148                Main.pref.put(PREF_ROLEBOX + ".visible", true);
    134149                toggleRolePanelButtonTop.setVisible(false);
    135150            }
    136151        });
     152        rolePanel.setVisible(Main.pref.getBoolean(PREF_ROLEBOX + ".visible", true));
    137153        toggleRolePanelButtonTop.setVisible(!rolePanel.isVisible());
     154        lastSelectedRole = Main.pref.get(PREF_ROLEBOX + ".lastrole");
    138155
    139156        sortAndFixAction.addPropertyChangeListener(new PropertyChangeListener() {
     
    155172        JPanel bottomLine = new JPanel(new GridBagLayout());
    156173        bottomLine.add(new JButton(new CreateRelationAction(chosenRelation)), GBC.std());
    157         bottomLine.add(new JButton(new CreateMultipolygonAction(chosenRelation)), GBC.std());
     174        final JButton multipolygonButton = new JButton(new CreateMultipolygonAction(chosenRelation));
     175        bottomLine.add(multipolygonButton, GBC.std());
     176//        bottomLine.add(sizeButton(new JButton(new MultipolygonSettingsAction()), 16, 0), GBC.std().fill(GBC.VERTICAL));
    158177        bottomLine.add(Box.createHorizontalGlue(), GBC.std().fill());
    159178        bottomLine.add(new JButton(new FindRelationAction(chosenRelation)), GBC.eol());
    160179        rcPanel.add(sizeButton(bottomLine, 0, 24), BorderLayout.SOUTH);
    161180
     181        multipolygonButton.addMouseListener(new MouseAdapter() {
     182            @Override
     183            public void mousePressed( MouseEvent e ) {
     184                checkPopup(e);
     185            }
     186
     187            @Override
     188            public void mouseReleased( MouseEvent e ) {
     189                checkPopup(e);
     190            }
     191
     192            private void checkPopup( MouseEvent e ) {
     193                if( e.isPopupTrigger() )
     194                    multiPopupMenu.show(e.getComponent(), e.getX(), e.getY());
     195            }
     196        });
     197
    162198        add(rcPanel, BorderLayout.CENTER);
    163 
    164         popupMenu = new ChosenRelationPopupMenu();
    165199    }
    166200
     
    223257        MapView.removeEditLayerChangeListener(this);
    224258        DatasetEventManager.getInstance().removeDatasetListener(chosenRelation);
     259        chosenRelation.clear();
    225260    }
    226261
     
    319354    }
    320355
    321     private static final Map<String, String[]> possibleRoles = new HashMap<String, String[]>();
    322     static {
    323         possibleRoles.put("boundary", new String[] {"admin_centre", "label", "subarea"});
    324         possibleRoles.put("route", new String[] {"forward", "backward", "stop", "platform"});
    325         possibleRoles.put("restriction", new String[] {"from", "to", "via", "location_hint"});
    326         possibleRoles.put("enforcement", new String[] {"device", "from", "to", "force"});
    327         possibleRoles.put("destination_sign", new String[] {"to", "from", "intersection", "sign"});
    328         possibleRoles.put("site", new String[] {"perimeter", "entrance", "label"});
    329         possibleRoles.put("bridge", new String[] {"across", "under", "outline", "edge"});
    330         possibleRoles.put("tunnel", new String[] {"through", "outline", "edge"});
    331         possibleRoles.put("surveillance", new String[] {"camera", "extent", "visible", "hidden"});
    332         possibleRoles.put("street", new String[] {"street", "address", "house", "associated"});
    333         possibleRoles.put("collection", new String[] {"member", "street", "river", "railway", "address", "associated"});
     356    private static final String POSSIBLE_ROLES_FILE = "relcontext/possible_roles.txt";
     357    private static final Map<String, List<String>> possibleRoles = loadRoles();
     358
     359    private static Map<String, List<String>> loadRoles() {
     360        Map<String, List<String>> result = new HashMap<String, List<String>>();
     361        try {
     362            ClassLoader classLoader = RelContextDialog.class.getClassLoader();
     363            final InputStream possibleRolesStream = classLoader.getResourceAsStream(POSSIBLE_ROLES_FILE);
     364            BufferedReader r = new BufferedReader(new InputStreamReader(possibleRolesStream));
     365            while( r.ready() ) {
     366                String line = r.readLine();
     367                StringTokenizer t = new StringTokenizer(line, " ,;:\"");
     368                if( t.hasMoreTokens() ) {
     369                    String type = t.nextToken();
     370                    List<String> roles = new ArrayList<String>();
     371                    while( t.hasMoreTokens() )
     372                        roles.add(t.nextToken());
     373                    result.put(type, roles);
     374                }
     375            }
     376            r.close();
     377        } catch( Exception e ) {
     378            System.err.println("[RelToolbox] Error reading possible roles file.");
     379            e.printStackTrace();
     380        }
     381        return result;
    334382    }
    335383
     
    344392            }
    345393            if( chosenRelation.get().get("type") != null ) {
    346                 String[] values = possibleRoles.get(chosenRelation.get().get("type"));
     394                List<String> values = possibleRoles.get(chosenRelation.get().get("type"));
    347395                if( values != null )
    348                     items.addAll(Arrays.asList(values));
     396                    items.addAll(values);
    349397            }
    350398            for( RelationMember m : chosenRelation.get().getMembers() )
     
    354402        if( currentRole != null && currentRole.length() > 1 ) {
    355403            lastSelectedRole = currentRole;
     404            Main.pref.put(PREF_ROLEBOX + ".lastrole", lastSelectedRole);
    356405        }
    357406        roleBox.setPossibleItems(items);
     
    456505
    457506        public void actionPerformed( ActionEvent e ) {
     507            Main.pref.put(PREF_ROLEBOX + ".visible", !component.isVisible());
    458508            component.setVisible(!component.isVisible());
    459509        }
     
    521571        }
    522572    }
     573
     574    private class MultipolygonSettingsAction extends AbstractAction {
     575        public MultipolygonSettingsAction() {
     576            super();
     577            putValue(SMALL_ICON, ImageProvider.get("svpRight"));
     578            putValue(SHORT_DESCRIPTION, tr("Change multipolygon creation settings"));
     579        }
     580
     581        public void actionPerformed( ActionEvent e ) {
     582            Component c = e.getSource() instanceof Component ? (Component)e.getSource() : Main.parent;
     583            Point p = getMousePosition();
     584            multiPopupMenu.show(c, 0, 0);
     585        }
     586    }
     587
     588    private class MultipolygonSettingsPopup extends JPopupMenu implements ActionListener {
     589        public MultipolygonSettingsPopup() {
     590            super();
     591            addMenuItem("boundary", "Create administrative boundary relations");
     592            addMenuItem("boundaryways", "Add tags boundary and admin_level to boundary relation ways");
     593            addMenuItem("tags", "Move area tags from contour to relation").setEnabled(false);
     594            addMenuItem("single", "Create a single multipolygon for multiple outer contours").setEnabled(false);
     595        }
     596
     597        protected final JCheckBoxMenuItem addMenuItem( String property, String title ) {
     598            String fullProperty = PREF_PREFIX + ".multipolygon." + property;
     599            JCheckBoxMenuItem item = new JCheckBoxMenuItem(tr(title));
     600            item.setSelected(Main.pref.getBoolean(fullProperty, CreateMultipolygonAction.getDefaultPropertyValue(property)));
     601            item.setActionCommand(fullProperty);
     602            item.addActionListener(this);
     603            add(item);
     604            return item;
     605        }
     606
     607        public void actionPerformed( ActionEvent e ) {
     608            String property = e.getActionCommand();
     609            if( property != null && property.length() > 0 && e.getSource() instanceof JCheckBoxMenuItem ) {
     610                boolean value = ((JCheckBoxMenuItem)e.getSource()).isSelected();
     611                Main.pref.put(property, value);
     612                show(getInvoker(), getX(), getY());
     613            }
     614        }
     615    }
    523616}
  • applications/editors/josm/plugins/relcontext/src/relcontext/actions/CreateMultipolygonAction.java

    r25682 r25692  
    11package relcontext.actions;
    22
    3 import org.openstreetmap.josm.data.osm.OsmPrimitive;
     3import java.awt.Dialog.ModalityType;
     4import java.awt.GridBagLayout;
    45import static org.openstreetmap.josm.tools.I18n.tr;
    56import java.awt.event.ActionEvent;
     7import java.awt.event.ActionListener;
    68import java.util.*;
    7 import javax.swing.JOptionPane;
     9import javax.swing.*;
    810import org.openstreetmap.josm.Main;
    911import org.openstreetmap.josm.actions.JosmAction;
    10 import org.openstreetmap.josm.command.AddCommand;
    11 import org.openstreetmap.josm.command.ChangePropertyCommand;
    12 import org.openstreetmap.josm.command.Command;
    13 import org.openstreetmap.josm.command.SequenceCommand;
    14 import org.openstreetmap.josm.data.osm.MultipolygonCreate;
    15 import org.openstreetmap.josm.data.osm.Relation;
    16 import org.openstreetmap.josm.data.osm.RelationMember;
    17 import org.openstreetmap.josm.data.osm.Way;
     12import org.openstreetmap.josm.command.*;
     13import org.openstreetmap.josm.data.osm.*;
     14import org.openstreetmap.josm.tools.GBC;
    1815import relcontext.ChosenRelation;
    1916
     
    2623public class CreateMultipolygonAction extends JosmAction {
    2724    private static final String ACTION_NAME = "Create relation";
     25    private static final String PREF_MULTIPOLY = "reltoolbox.multipolygon.";
    2826    protected ChosenRelation chRel;
    2927
     
    3634    public CreateMultipolygonAction() {
    3735        this(null);
     36    }
     37   
     38    public static boolean getDefaultPropertyValue( String property ) {
     39        if( property.equals("boundary") ) return false;
     40        else if( property.equals("boundaryways") ) return true;
     41        else if( property.equals("tags") ) return false;
     42        else if( property.equals("single") ) return true;
     43        throw new IllegalArgumentException(property);
     44    }
     45
     46    private boolean getPref( String property ) {
     47        return Main.pref.getBoolean(PREF_MULTIPOLY + property, getDefaultPropertyValue(property));
    3848    }
    3949
     
    4757        }
    4858        Relation rel = new Relation();
    49         rel.put("type", "multipolygon");
     59        boolean isBoundary = getPref("boundary");
     60        if( isBoundary ) {
     61            rel.put("type", "boundary");
     62            rel.put("boundary", "administrative");
     63            askForAdminLevelAndName(rel);
     64        } else
     65            rel.put("type", "multipolygon");
    5066        for( MultipolygonCreate.JoinedPolygon poly : mpc.outerWays )
    5167            for( Way w : poly.ways )
     
    5470            for( Way w : poly.ways )
    5571                rel.addMember(new RelationMember("inner", w));
     72        if( isBoundary )
     73            addBoundaryMembers(rel);
    5674        List<Command> list = removeTagsFromInnerWays(rel);
     75        if( isBoundary && getPref("boundaryways") )
     76            list.addAll(fixWayTagsForBoundary(rel));
    5777        list.add(new AddCommand(rel));
    5878        Main.main.undoRedo.add(new SequenceCommand(tr("Create multipolygon"), list));
     
    7797            enabled = false;
    7898        else {
    79             for( OsmPrimitive p : selection )
    80                 if( !(p instanceof Way) ) {
    81                     enabled = false;
    82                     break;
    83                 }
     99            if( !getPref("boundary") ) {
     100                for( OsmPrimitive p : selection ) {
     101                    if( !(p instanceof Way) ) {
     102                        enabled = false;
     103                        break;
     104                    }
     105                }
     106            }
    84107        }
    85108        setEnabled(enabled);
     109    }
     110
     111    /**
     112     * Add selected nodes and relations with corresponding roles.
     113     */
     114    private void addBoundaryMembers( Relation rel ) {
     115        for( OsmPrimitive p : getCurrentDataSet().getSelected() ) {
     116            String role = null;
     117            if( p.getType().equals(OsmPrimitiveType.RELATION) ) {
     118                role = "subarea";
     119            } else if( p.getType().equals(OsmPrimitiveType.NODE) ) {
     120                Node n = (Node)p;
     121                if( !n.isIncomplete() ) {
     122                    if( n.hasKey("place") )
     123                        role = "admin_centre";
     124                    else
     125                        role = "label";
     126                }
     127            }
     128            if( role != null )
     129                rel.addMember(new RelationMember(role, p));
     130        }
     131    }
     132
     133    /**
     134     * For all untagged ways in relation, add tags boundary and admin_level.
     135     */
     136    private List<Command> fixWayTagsForBoundary( Relation rel ) {
     137        List<Command> commands = new ArrayList<Command>();
     138        if( !rel.hasKey("boundary") || !rel.hasKey("admin_level") )
     139            return commands;
     140        String adminLevelStr = rel.get("admin_level");
     141        int adminLevel = 0;
     142        try {
     143            adminLevel = Integer.parseInt(adminLevelStr);
     144        } catch( NumberFormatException e ) {
     145            return commands;
     146        }
     147        Set<OsmPrimitive> waysBoundary = new HashSet<OsmPrimitive>();
     148        Set<OsmPrimitive> waysAdminLevel = new HashSet<OsmPrimitive>();
     149        for( OsmPrimitive p : rel.getMemberPrimitives() ) {
     150            if( p instanceof Way ) {
     151                int count = 0;
     152                if( p.hasKey("boundary") && p.get("boundary").equals("administrative") )
     153                    count++;
     154                if( p.hasKey("admin_level") )
     155                    count++;
     156                if( p.keySet().size() - count == 0 ) {
     157                    if( !p.hasKey("boundary") )
     158                        waysBoundary.add(p);
     159                    if( !p.hasKey("admin_level") ) {
     160                        waysAdminLevel.add(p);
     161                    } else {
     162                        try {
     163                            int oldAdminLevel = Integer.parseInt(p.get("admin_level"));
     164                            if( oldAdminLevel > adminLevel )
     165                                waysAdminLevel.add(p);
     166                        } catch( NumberFormatException e ) {
     167                            waysAdminLevel.add(p); // some garbage, replace it
     168                        }
     169                    }
     170                }
     171            }
     172        }
     173        if( !waysBoundary.isEmpty() )
     174            commands.add(new ChangePropertyCommand(waysBoundary, "boundary", "administrative"));
     175        if( !waysAdminLevel.isEmpty() )
     176            commands.add(new ChangePropertyCommand(waysAdminLevel, "admin_level", adminLevelStr));
     177        return commands;
    86178    }
    87179
     
    137229        return commands;
    138230    }
     231
     232    private void askForAdminLevelAndName( Relation rel ) {
     233        JPanel panel = new JPanel(new GridBagLayout());
     234        panel.add(new JLabel(tr("Enter admin level and name for the border relation:")), GBC.eol().insets(0, 0, 0, 5));
     235
     236        final JTextField admin = new JTextField();
     237        admin.setText(Main.pref.get(PREF_MULTIPOLY + "lastadmin", ""));
     238        panel.add(new JLabel(tr("Admin level")), GBC.std());
     239        panel.add(Box.createHorizontalStrut(10), GBC.std());
     240        panel.add(admin, GBC.eol().fill(GBC.HORIZONTAL));
     241
     242        final JTextField name = new JTextField();
     243        panel.add(new JLabel(tr("Name")), GBC.std());
     244        panel.add(Box.createHorizontalStrut(10), GBC.std());
     245        panel.add(name, GBC.eol().fill(GBC.HORIZONTAL));
     246
     247        final JOptionPane optionPane = new JOptionPane(panel, JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION) {
     248            @Override
     249            public void selectInitialValue() {
     250                admin.requestFocusInWindow();
     251                admin.selectAll();
     252            }
     253        };
     254        final JDialog dlg = optionPane.createDialog(Main.parent, tr("Create relation"));
     255        dlg.setModalityType(ModalityType.DOCUMENT_MODAL);
     256
     257        name.addActionListener(new ActionListener() {
     258            public void actionPerformed( ActionEvent e ) {
     259                dlg.setVisible(false);
     260                optionPane.setValue(JOptionPane.OK_OPTION);
     261            }
     262        });
     263
     264        dlg.setVisible(true);
     265
     266        Object answer = optionPane.getValue();
     267        if( answer == null || answer == JOptionPane.UNINITIALIZED_VALUE
     268                || (answer instanceof Integer && (Integer)answer != JOptionPane.OK_OPTION) ) {
     269            return;
     270        }
     271
     272        String admin_level = admin.getText().trim();
     273        String new_name = name.getText().trim();
     274        if( admin_level.equals("10") || (admin_level.length() == 1 && Character.isDigit(admin_level.charAt(0))) ) {
     275            rel.put("admin_level", admin_level);
     276            Main.pref.put(PREF_MULTIPOLY + "lastadmin", admin_level);
     277        }
     278        if( new_name.length() > 0 )
     279            rel.put("name", new_name);
     280    }
    139281}
  • applications/editors/josm/plugins/relcontext/src/relcontext/actions/CreateRelationAction.java

    r25688 r25692  
    2323import org.openstreetmap.josm.tools.GBC;
    2424import relcontext.ChosenRelation;
     25import relcontext.RelContextDialog;
    2526
    2627/**
     
    3233public class CreateRelationAction extends JosmAction {
    3334    private static final String ACTION_NAME = "Create relation";
     35    private static final String PREF_LASTTYPE = "reltoolbox.createrelation.lasttype";
    3436    protected ChosenRelation chRel;
    3537
     
    9092        keys.setPossibleItems(RELATION_TYPES);
    9193        keys.setEditable(true);
     94        keys.getEditor().setItem(Main.pref.get(PREF_LASTTYPE, "multipolygon"));
    9295
    9396        panel.add(new JLabel(tr("Type")), GBC.std());
     
    120123        }
    121124
    122         return keys.getEditor().getItem().toString().trim();
     125        String result = keys.getEditor().getItem().toString().trim();
     126        Main.pref.put(PREF_LASTTYPE, result);
     127        return result;
    123128    }
    124129}
  • applications/editors/josm/plugins/relcontext/src/relcontext/actions/SortAndFixAction.java

    r25688 r25692  
    116116        for( int i = 0; i < r.getMembersCount(); i++ ) {
    117117            RelationMember m = r.getMember(i);
    118             if( m.getType().equals(OsmPrimitiveType.WAY) ) {
     118            if( m.isWay() ) {
    119119                String role = null;
    120120                if( outerWays.contains((Way)m.getMember()) )
     
    137137            RelationMember m = r.getMember(i);
    138138            String role = null;
    139             if( m.getType().equals(OsmPrimitiveType.RELATION) )
     139            if( m.isRelation() )
    140140                role = "subarea";
    141             else if( m.getType().equals(OsmPrimitiveType.NODE) ) {
     141            else if( m.isNode() ) {
    142142                Node n = (Node)m.getMember();
    143143                if( !n.isIncomplete() ) {
Note: See TracChangeset for help on using the changeset viewer.