Ignore:
Timestamp:
2014-04-27T16:28:56+02:00 (10 years ago)
Author:
akks
Message:

[josm_utilsplugin2]: select boundary by double-click; multitagger table highlights

Location:
applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/UtilsPlugin2.java

    r30384 r30419  
    22package org.openstreetmap.josm.plugins.utilsplugin2;
    33
     4import java.awt.event.MouseAdapter;
     5import java.awt.event.MouseEvent;
     6import java.awt.event.MouseListener;
    47import javax.swing.JMenu;
    58import javax.swing.JMenuItem;
     9import javax.swing.SwingUtilities;
    610
    711import org.openstreetmap.josm.Main;
    812import org.openstreetmap.josm.actions.search.SearchCompiler;
     13import org.openstreetmap.josm.data.coor.EastNorth;
    914import org.openstreetmap.josm.gui.MainMenu;
    1015import org.openstreetmap.josm.gui.MapFrame;
     
    127132        SearchCompiler.addMatchFactory(new UtilsSimpleMatchFactory());
    128133    }
    129 
     134   
     135    MouseListener mouseListener = new MouseAdapter() {
     136        @Override
     137        public void mouseReleased(final MouseEvent e) {
     138            if (e.getButton()==MouseEvent.BUTTON1 &&
     139                    e.getClickCount() > 1 && Main.isDisplayingMapView() && Main.map.mapMode == Main.map.mapModeSelect &&
     140                    (0 == (e.getModifiersEx() & (MouseEvent.ALT_DOWN_MASK + MouseEvent.CTRL_DOWN_MASK + MouseEvent.SHIFT_DOWN_MASK) ))) {
     141                SwingUtilities.invokeLater(new Runnable() {
     142                    @Override
     143                    public void run() {
     144                        EastNorth en = Main.map.mapView.getEastNorth(e.getX(), e.getY());
     145                        SelectBoundaryAction.selectByInternalPoint(en);
     146                    }
     147                });
     148            }
     149        }
     150    };
     151   
    130152    @Override
    131153    public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
     
    160182        drawArc.setEnabled(enabled);
    161183        multiTag.setEnabled(enabled);
     184        if (oldFrame!=null && oldFrame.mapView!=null) oldFrame.mapView.removeMouseListener(mouseListener);
     185        if (newFrame!=null && newFrame.mapView!=null && Main.pref.getBoolean(UtilsPluginPreferences.PREF_DOUBLECLICK, true))
     186            newFrame.mapView.addMouseListener(mouseListener);
    162187    }
    163188   
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/customurl/UtilsPluginPreferences.java

    r30002 r30419  
    1414import org.openstreetmap.josm.gui.widgets.HtmlPanel;
    1515import java.awt.event.ActionListener;
     16import javax.swing.JCheckBox;
    1617import javax.swing.JPanel;
    1718import javax.swing.ListSelectionModel;
    1819import javax.swing.event.TableModelListener;
    1920import javax.swing.table.DefaultTableModel;
     21import org.openstreetmap.josm.Main;
    2022import org.openstreetmap.josm.gui.preferences.DefaultTabPreferenceSetting;
    2123import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane;
     
    3032    JButton loadButton;
    3133    JButton saveButton;
     34    JCheckBox dblClick = new JCheckBox(tr("Double click selects object by its internal point"));
     35    public static final String PREF_DOUBLECLICK = "utilsplugin2.doubleclick";
    3236
    3337    public UtilsPluginPreferences() {
    34         super("utils", tr("Utilsplugin2 settings [TESTING]"), tr("Here you can change some preferences of Utilsplugin2 functions"));
     38        super("utils", tr("Utilsplugin2 settings"), tr("Here you can change some preferences of Utilsplugin2 functions"));
    3539    }
    3640
     
    3842    public void addGui(PreferenceTabbedPane gui) {
    3943        JPanel all = new JPanel(new GridBagLayout());
    40 
    41         // FIXME: get rid of hardcoded URLS
    4244
    4345        URLList.getSelectedURL();
     
    7981                + " Your can manually load settings from file <b>customurl.txt</b> in JOSM folder"));
    8082
     83        dblClick.setSelected(Main.pref.getBoolean(PREF_DOUBLECLICK, true));
     84        all.add(dblClick, GBC.std().insets(5,10,0,0));
     85       
    8186        all.add(new JLabel(tr("Custom URL configuration")),GBC.std().insets(5,10,0,0));
    8287        all.add(resetButton,GBC.std().insets(25,10,0,0));
     
    129134        List<String> lst = readItemsFromTable();
    130135        URLList.updateURLList(lst);
    131 
     136        Main.pref.put(PREF_DOUBLECLICK, dblClick.isSelected());
    132137        return false;
    133138    }
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/multitagger/MultiTagDialog.java

    r30389 r30419  
    11package org.openstreetmap.josm.plugins.utilsplugin2.multitagger;
    22
     3import java.awt.Color;
    34import java.awt.Component;
    45import java.awt.Dimension;
     
    2021import static javax.swing.Action.SHORT_DESCRIPTION;
    2122import javax.swing.BoxLayout;
     23import javax.swing.DefaultCellEditor;
    2224import javax.swing.JButton;
    2325import javax.swing.JComponent;
     
    4951import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
    5052import org.openstreetmap.josm.tools.GBC;
     53import static org.openstreetmap.josm.tools.I18n.marktr;
    5154import static org.openstreetmap.josm.tools.I18n.tr;
    5255import org.openstreetmap.josm.tools.ImageProvider;
     56import org.openstreetmap.josm.tools.Shortcut;
    5357import org.openstreetmap.josm.tools.WindowGeometry;
    5458
     
    116120        t.setColumnSelectionAllowed(true);
    117121        t.setDefaultRenderer(OsmPrimitiveType.class, new PrimitiveTypeIconRenderer());
     122        t.setDefaultRenderer(String.class, new ColoredRenderer());
    118123        t.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
    119124        t.getSelectionModel().addListSelectionListener(selectionListener);
     
    346351        initAutocompletion();
    347352        tableModel.fireTableDataChanged();
    348     }   
     353    }
     354   
     355    class ColoredRenderer extends DefaultTableCellRenderer {
     356        private final Color highlightColor =
     357                Main.pref.getColor( marktr("Multitag Background: highlight"),
     358                        new Color(255,255,200));
     359        @Override
     360        public Component getTableCellRendererComponent(JTable table, Object value, boolean
     361                isSelected, boolean hasFocus, int row, int column) {
     362            int row1 = tbl.convertRowIndexToModel(row);
     363            JLabel label = (JLabel) super.getTableCellRendererComponent(
     364                table, value, isSelected, hasFocus, row, column);
     365            if (tbl.isRowSelected(row1) && !tbl.isColumnSelected(column)) {
     366                label.setBackground(highlightColor);
     367            } else {
     368                if (isSelected) {
     369                    label.setBackground(Main.pref.getUIColor("Table.selectionBackground"));
     370                } else {
     371                    label.setBackground(Main.pref.getUIColor("Table.background"));
     372                }
     373            }
     374            return label;
     375        }
     376    }
    349377}
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/NodeWayUtils.java

    r30200 r30419  
    176176        int s = newNodes.size();
    177177        for (Way w: initWays) {
    178                 newNodes.addAll(w.getNodes());
     178            newNodes.addAll(w.getNodes());
    179179        }
    180180        return newNodes.size()-s;
     
    182182
    183183    public static void addWaysIntersectingWaysRecursively
    184             (Collection<Way> allWays, Collection<Way> initWays, Set<Way> newWays) {
    185             Set<Way> foundWays = new HashSet<Way>();
    186             foundWays.addAll(initWays);
    187             newWays.addAll(initWays);
    188             Set<Way> newFoundWays;
    189 
    190             int level=0,c;
    191             do {
    192                  c=0;
    193                  newFoundWays = new HashSet<Way>();
    194                  for (Way w : foundWays){
    195                       c+=addWaysIntersectingWay(allWays, w, newFoundWays,newWays);
    196                  }
    197                  foundWays = newFoundWays;
    198                  newWays.addAll(newFoundWays);
    199                  level++;
     184        (Collection<Way> allWays, Collection<Way> initWays, Set<Way> newWays) {
     185        Set<Way> foundWays = new HashSet<Way>();
     186        foundWays.addAll(initWays);
     187        newWays.addAll(initWays);
     188        Set<Way> newFoundWays;
     189
     190        int level=0,c;
     191        do {
     192             c=0;
     193             newFoundWays = new HashSet<Way>();
     194             for (Way w : foundWays){
     195                  c+=addWaysIntersectingWay(allWays, w, newFoundWays,newWays);
     196             }
     197             foundWays = newFoundWays;
     198             newWays.addAll(newFoundWays);
     199             level++;
    200200//                 System.out.printf("%d: %d ways added to selection intersectiong\n",level,c);
    201                  if (c>maxWays1) {
    202                         new Notification(
    203                             tr("Too many ways are added: {0}!",c)
    204                             ).setIcon(JOptionPane.WARNING_MESSAGE).show(); 
    205                        return;
    206                  }
    207             } while ( c >0 && level < maxLevel );
     201             if (c>maxWays1) {
     202                    new Notification(
     203                        tr("Too many ways are added: {0}!",c)
     204                        ).setIcon(JOptionPane.WARNING_MESSAGE).show(); 
     205                   return;
     206             }
     207        } while ( c >0 && level < maxLevel );
    208208    }
    209209
     
    211211            (Collection<Way> initWays, Set<Way> newWays)
    212212    {
    213             //long t = System.currentTimeMillis();
    214             int level=0,c;
    215             newWays.addAll(initWays);
    216             do {
    217                  c=0;
    218                  Set<Way> foundWays = new HashSet<Way>();
    219                  foundWays.addAll(newWays);
    220                  for (Way w : foundWays){
    221                       c+=addWaysConnectedToWay(w, newWays);
    222                  }
    223                  level++;
     213        //long t = System.currentTimeMillis();
     214        int level=0,c;
     215        newWays.addAll(initWays);
     216        do {
     217             c=0;
     218             Set<Way> foundWays = new HashSet<Way>();
     219             foundWays.addAll(newWays);
     220             for (Way w : foundWays){
     221                  c+=addWaysConnectedToWay(w, newWays);
     222             }
     223             level++;
    224224//                 System.out.printf("%d: %d ways added to selection\n",level,c);
    225                  if (c>maxWays) {
    226                         new Notification(
    227                             tr("Too many ways are added: {0}!",c)
    228                             ).setIcon(JOptionPane.WARNING_MESSAGE).show();                       
    229                        return;
    230                  }
    231             } while ( c >0 && level < maxLevel );
    232            // System.out.println("time = "+(System.currentTimeMillis()-t)+" ways = "+newWays.size());
     225             if (c>maxWays) {
     226                new Notification(
     227                    tr("Too many ways are added: {0}!",c)
     228                    ).setIcon(JOptionPane.WARNING_MESSAGE).show();                       
     229               return;
     230             }
     231        } while ( c >0 && level < maxLevel );
     232       // System.out.println("time = "+(System.currentTimeMillis()-t)+" ways = "+newWays.size());
    233233    }
    234234
     
    344344        }
    345345    }
    346 
     346   
     347    static boolean isPointInsideMultipolygon(EastNorth p, Relation rel) {
     348        Set<Way> usedWays = OsmPrimitive.getFilteredSet(rel.getMemberPrimitives(), Way.class);
     349        return isPointInsidePolygon(p, buildPointList(usedWays));
     350    }
     351           
    347352    static void addAllInsideMultipolygon(DataSet data, Relation rel, Set<Way> newWays, Set<Node> newNodes) {
    348353        if (!rel.isMultipolygon()) return;
    349354        BBox box = rel.getBBox();
    350         Set<Way> usedWays = OsmPrimitive.getFilteredSet(rel.getMemberPrimitives(), Way.class);
    351         List<EastNorth> polyPoints = new ArrayList<EastNorth>(10000);
    352        
    353         for (Way way: usedWays) {
    354             List<Node> polyNodes = way.getNodes();
    355             // converts all points to EastNorth
    356             for (Node n: polyNodes) polyPoints.add(n.getEastNorth());
    357             polyPoints.add(null); // next segment indicator
    358         }
    359        
    360        
     355        Collection<Way> usedWays = rel.getMemberPrimitives(Way.class);
     356        List<EastNorth> polyPoints = buildPointList(usedWays);
     357       
    361358        List<Node> searchNodes = data.searchNodes(box);
    362359        Set<Node> newestNodes = new HashSet<Node>();
     
    387384        if (!way.isClosed()) return;
    388385        BBox box = way.getBBox();
    389         List<Node> polyNodes = way.getNodes();
    390         List<EastNorth> polyPoints = new ArrayList<EastNorth>(polyNodes.size()+5);
    391        
    392         // converts all points to EastNorth
    393         for (Node n: polyNodes) polyPoints.add(n.getEastNorth()); 
     386        Iterable<EastNorth> polyPoints = getWayPoints(way);
    394387       
    395388        List<Node> searchNodes = data.searchNodes(box);
     
    414407    }
    415408   
    416     public static boolean isPointInsidePolygon(EastNorth point, List<EastNorth> polygonPoints) {
     409    public static boolean isPointInsidePolygon(EastNorth point, Iterable<EastNorth> polygonPoints) {
    417410        int n = getRayIntersectionsCount(point, polygonPoints);
    418411        if (n<0) return true; // we are near node or near edge
    419412        return (n%2==1);
    420413    }
    421    
     414
    422415    /**
     416     * @param point - point to start an OX-parallel  ray
     417     * @param polygonPoints - poits forming bundary, use null to split unconnected segmants
    423418     * @return 0 =  not inside polygon, 1 = strictly inside, 2 = near edge, 3 = near vertex
    424419     */
    425     public static int getRayIntersectionsCount(EastNorth point, List<EastNorth> polygonPoints) {
     420    public static int getRayIntersectionsCount(EastNorth point, Iterable<EastNorth> polygonPoints) {
    426421        if (point==null) return 0;
    427422        EastNorth oldPoint = null;
     
    512507    }
    513508
    514 
    515 
     509    private static List<EastNorth> buildPointList(Iterable<Way> ways) {
     510        ArrayList<EastNorth> points = new ArrayList<EastNorth>(1000);
     511        for (Way way: ways) {
     512            for (EastNorth en: getWayPoints(way)) points.add(en);
     513            points.add(null); // next segment indicator
     514        }
     515        return points;
     516    }
     517   
     518    public static Iterable<EastNorth> getWayPoints(final Way w) {
     519        return new Iterable<EastNorth>() {
     520            @Override
     521            public Iterator<EastNorth> iterator() {
     522                return new Iterator<EastNorth>() {
     523                    int idx = 0;
     524                    @Override public boolean hasNext() {
     525                        return idx < w.getNodesCount();
     526                    }
     527                    @Override public EastNorth next() {
     528                        return w.getNode(idx++).getEastNorth();
     529                    }
     530                };
     531            }
     532        };
     533    }
     534   
    516535}
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/SelectBoundaryAction.java

    r30177 r30419  
    22package org.openstreetmap.josm.plugins.utilsplugin2.selection;
    33
     4import java.awt.Point;
    45import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
    56import static org.openstreetmap.josm.tools.I18n.tr;
     
    78import java.awt.event.ActionEvent;
    89import java.awt.event.KeyEvent;
    9 import java.util.ArrayList;
    10 import java.util.Arrays;
    1110import java.util.Collection;
     11import java.util.Collections;
    1212import java.util.HashSet;
    13 import java.util.List;
    1413import java.util.Set;
     14import java.util.TreeMap;
    1515
    1616import javax.swing.JOptionPane;
     17import org.openstreetmap.josm.Main;
    1718
    18 import org.openstreetmap.josm.Main;
    1919import org.openstreetmap.josm.actions.JosmAction;
     20import org.openstreetmap.josm.data.coor.EastNorth;
     21import org.openstreetmap.josm.data.osm.BBox;
    2022import org.openstreetmap.josm.data.osm.Node;
    2123import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2224import org.openstreetmap.josm.data.osm.Relation;
     25import org.openstreetmap.josm.data.osm.RelationMember;
    2326import org.openstreetmap.josm.data.osm.Way;
    2427import org.openstreetmap.josm.gui.Notification;
     28import org.openstreetmap.josm.tools.Geometry;
    2529
    2630import org.openstreetmap.josm.tools.Shortcut;
     
    3943        putValue("help", ht("/Action/SelectAreaBoundary"));
    4044    }
    41 
     45   
     46    public static void selectByInternalPoint(EastNorth e) {
     47        //Node n= new Node(e);
     48        TreeMap<Double, OsmPrimitive> found = new TreeMap<>();
     49        for (Way w: getCurrentDataSet().getWays()) {
     50            if (w.isUsable() && w.isClosed() )  {
     51                //if (Geometry.nodeInsidePolygon(n, w.getNodes())) {
     52                if (NodeWayUtils.isPointInsidePolygon(e, NodeWayUtils.getWayPoints(w))) {
     53                    found.put(Geometry.closedWayArea(w), w);
     54                }
     55            }
     56        }
     57        for (Relation r: getCurrentDataSet().getRelations()) {
     58            if (r.isUsable() && r.isMultipolygon())  {
     59                //if (Geometry.isNodeInsideMultiPolygon(n, r, null)) {
     60                if (NodeWayUtils.isPointInsideMultipolygon(e, r)) {
     61                    for (RelationMember m: r.getMembers()) {
     62                        if (m.isWay() && m.getWay().isClosed()) {
     63                            found.values().remove(m.getWay());
     64                        }
     65                    }
     66                    // estimate multipolygon size by its bounding box area
     67                    BBox bBox = r.getBBox();
     68                    EastNorth en1 = Main.map.mapView.getProjection().latlon2eastNorth(bBox.getTopLeft());
     69                    EastNorth en2 = Main.map.mapView.getProjection().latlon2eastNorth(bBox.getBottomRight());
     70                    double s = Math.abs((en1.east()-en2.east())*(en1.north()-en2.north()));
     71                    if (s==0) s=1e8;
     72                    found.put(s, r);
     73                }
     74            }
     75        }
     76       
     77        if (!found.isEmpty()) {
     78            getCurrentDataSet().setSelected(Collections.singletonList(
     79                found.firstEntry().getValue()));
     80        }
     81    }
     82   
    4283    @Override
    4384    public void actionPerformed(ActionEvent e) {
     
    4586        Set<Node> selectedNodes = OsmPrimitive.getFilteredSet(getCurrentDataSet().getSelected(), Node.class);
    4687       
    47         Set<Way> newWays = new HashSet<Way>();
     88        Set<Way> newWays = new HashSet<>();
    4889       
    4990        Way w=null;
     
    5394                for (OsmPrimitive p : selectedNodes.iterator().next().getReferrers()) {
    5495                    if (p instanceof Way && p.isSelectable()) {
    55                         //if (w!=null) return; // ifwe want only one way
     96                        //if (w!=null) return; // if we want only one way
    5697                        w=(Way) p;
    5798                        break;
    5899                    }
    59100                }
     101            } else {
     102                Point p = Main.map.mapView.getMousePosition();
     103                selectByInternalPoint(Main.map.mapView.getEastNorth(p.x, p.y));
     104                return;
    60105            }
    61106        } else if (selectedWays.size()==1)  {
     
    95140            setEnabled(false);
    96141        } else {
    97             updateEnabledState(getCurrentDataSet().getSelected());
     142            setEnabled(true);
     143           // updateEnabledState(getCurrentDataSet().getSelected());
    98144        }
    99145    }
     
    102148    protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
    103149        if (selection == null) {
    104             setEnabled(false);
     150         //   setEnabled(false);
    105151            return;
    106152        }
    107         setEnabled(!selection.isEmpty());
     153        setEnabled(true);
     154        //setEnabled(!selection.isEmpty());
    108155    }
    109156}
Note: See TracChangeset for help on using the changeset viewer.