Ticket #25011: HouseNumberTaggingTool_increment_suffix.patch

File HouseNumberTaggingTool_increment_suffix.patch, 16.4 KB (added by Till_btn, 10 hours ago)
  • HouseNumberTaggingTool/src/org/openstreetmap/josm/plugins/housenumbertool/Dto.java

    diff --git a/HouseNumberTaggingTool/src/org/openstreetmap/josm/plugins/housenumbertool/Dto.java b/HouseNumberTaggingTool/src/org/openstreetmap/josm/plugins/housenumbertool/Dto.java
    index cf530825f..b7037dc51 100644
    a b public class Dto implements Serializable {  
    2222    private boolean saveHousenumber = true;
    2323
    2424    private boolean tagStreet = true; // use tag addr:street or addr:place
     25    private boolean incrementSuffix = false; // increment 1a, 1b, ... instead of 1, 2, ...
    2526   
    2627    private String building = "yes";
    2728    private String source;
    … … public class Dto implements Serializable {  
    163164        this.tagStreet = tagStreet;
    164165    }
    165166
     167    public boolean isIncrementSuffix() {
     168        return incrementSuffix;
     169    }
     170
     171    public void setIncrementSuffix(boolean incrementSuffix) {
     172        this.incrementSuffix = incrementSuffix;
     173    }
     174
    166175    public String getPlace() {
    167176        return place;
    168177    }
  • HouseNumberTaggingTool/src/org/openstreetmap/josm/plugins/housenumbertool/HouseNumberHelper.java

    diff --git a/HouseNumberTaggingTool/src/org/openstreetmap/josm/plugins/housenumbertool/HouseNumberHelper.java b/HouseNumberTaggingTool/src/org/openstreetmap/josm/plugins/housenumbertool/HouseNumberHelper.java
    index 1690c9091..c2b744569 100644
    a b import org.openstreetmap.josm.tools.Logging;  
    1010 * A helper class for incrementing addr:housenumber
    1111 */
    1212public final class HouseNumberHelper {
     13    /**
     14     * prefix, number, separator, letter suffix, number suffix, e.g. "12a", "12/1", "12-b"
     15     */
     16    private static final Pattern HOUSE_NUMBER_PATTERN = Pattern.compile("([^\\pN]+)?(\\pN+)([-/ ])?([^\\pN]+)?(\\pN+)?");
     17
    1318    private HouseNumberHelper() {
    1419        // Hide constructor
    1520    }
    … … public final class HouseNumberHelper {  
    2328    public static String incrementHouseNumber(String number, int increment) {
    2429        if (number != null) {
    2530            try {
    26                 Matcher m = Pattern.compile("([^\\pN]+)?(\\pN+)([^\\pN]+)?").matcher(number);
     31                Matcher m = HOUSE_NUMBER_PATTERN.matcher(number);
    2732                if (m.matches()) {
    28                     String prefix = m.group(1) != null ? m.group(1) : "";
    2933                    int n = Integer.parseInt(m.group(2)) + increment;
    30                     String suffix = m.group(3) != null ? m.group(3) : "";
    31                     return prefix + n + suffix;
     34                    return number.substring(0, m.start(2)) + n + number.substring(m.end(2));
    3235                }
    3336            } catch (NumberFormatException e) {
    3437                Logging.trace(e);
    … … public final class HouseNumberHelper {  
    3639        }
    3740        return null;
    3841    }
     42
     43    /**
     44     * Increment the suffix of a house number, e.g. 1 to 1a, 1a to 1b or 1/1 to 1/2
     45     * @param number The number to increment
     46     * @return The incremented number
     47     */
     48    public static String incrementHouseNumberSuffix(String number) {
     49        if (number != null) {
     50            try {
     51                Matcher m = HOUSE_NUMBER_PATTERN.matcher(number);
     52                if (m.matches()) {
     53                    String letter = m.group(4);
     54                    String suffixNumber = m.group(5);
     55                    if (suffixNumber != null) {
     56                        int n = Integer.parseInt(suffixNumber) + 1;
     57                        return number.substring(0, m.start(5)) + n;
     58                    } else if (letter != null) {
     59                        char next = (char) (letter.charAt(letter.length() - 1) + 1);
     60                        return number.substring(0, m.end(4) - 1) + next;
     61                    } else {
     62                        return number + "a";
     63                    }
     64                }
     65            } catch (NumberFormatException e) {
     66                Logging.trace(e);
     67            }
     68        }
     69        return null;
     70    }
     71
     72    /**
     73     * Check if a house number has a suffix like 1a or 1/1
     74     * @param number The house number
     75     * @return {@code true} if the number has a suffix
     76     */
     77    public static boolean hasSuffix(String number) {
     78        return number != null && !number.equals(removeSuffix(number));
     79    }
     80
     81    /**
     82     * Remove the suffix of a house number, e.g. 1a to 1
     83     * @param number The house number
     84     * @return The number without suffix
     85     */
     86    public static String removeSuffix(String number) {
     87        if (number != null) {
     88            Matcher m = HOUSE_NUMBER_PATTERN.matcher(number);
     89            if (m.matches()) {
     90                return number.substring(0, m.end(2));
     91            }
     92        }
     93        return number;
     94    }
    3995}
  • HouseNumberTaggingTool/src/org/openstreetmap/josm/plugins/housenumbertool/HouseNumberTaggingToolPlugin.java

    diff --git a/HouseNumberTaggingTool/src/org/openstreetmap/josm/plugins/housenumbertool/HouseNumberTaggingToolPlugin.java b/HouseNumberTaggingTool/src/org/openstreetmap/josm/plugins/housenumbertool/HouseNumberTaggingToolPlugin.java
    index b189e45a4..aa6cea477 100644
    a b  
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.plugins.housenumbertool;
    33
     4import java.io.File;
     5
    46import org.openstreetmap.josm.gui.MainApplication;
    57import org.openstreetmap.josm.gui.MainMenu;
    68import org.openstreetmap.josm.plugins.Plugin;
    … … import org.openstreetmap.josm.plugins.PluginInformation;  
    810
    911/**
    1012 * Simple tool to tag house numbers. Select house and press 'k'. Select your addr-tags and press OK.
     13 * Press 'shift+k' to switch between incrementing the number and the suffix.
    1114 */
    1215public class HouseNumberTaggingToolPlugin extends Plugin {
    1316
    … … public class HouseNumberTaggingToolPlugin extends Plugin {  
    1720     */
    1821    public HouseNumberTaggingToolPlugin(PluginInformation info) {
    1922        super(info);
    20         LaunchAction action = new LaunchAction(getPluginDirs().getUserDataDirectory(false));
    21         MainMenu.add(MainApplication.getMenu().dataMenu, action, false, 0);
     23        File pluginDir = getPluginDirs().getUserDataDirectory(false);
     24        MainMenu.add(MainApplication.getMenu().dataMenu, new LaunchAction(pluginDir), false, 0);
     25        MainMenu.add(MainApplication.getMenu().dataMenu, new LaunchAction(pluginDir, true), false, 1);
    2226    }
    2327}
  • HouseNumberTaggingTool/src/org/openstreetmap/josm/plugins/housenumbertool/LaunchAction.java

    diff --git a/HouseNumberTaggingTool/src/org/openstreetmap/josm/plugins/housenumbertool/LaunchAction.java b/HouseNumberTaggingTool/src/org/openstreetmap/josm/plugins/housenumbertool/LaunchAction.java
    index b6a49b3c3..400aa9ffe 100644
    a b public class LaunchAction extends JosmAction implements DataSelectionListener {  
    2323    private OsmPrimitive selection;
    2424
    2525    private final File pluginDir;
     26    private final boolean switchIncrement;
    2627
    2728    /**
    2829     * Constructs a new {@code LaunchAction}.
    2930     * @param pluginDir plugin directory
    3031     */
    3132    public LaunchAction(File pluginDir) {
    32         super(tr("HouseNumberTaggingTool"),
     33        this(pluginDir, false);
     34    }
     35
     36    /**
     37     * Constructs a new {@code LaunchAction}.
     38     * @param pluginDir plugin directory
     39     * @param switchIncrement if {@code true}, switch between incrementing the number and the suffix,
     40     * e.g. 1 to 1a or 1c to 2 (shortcut Shift+K)
     41     */
     42    public LaunchAction(File pluginDir, boolean switchIncrement) {
     43        super(switchIncrement ? tr("HouseNumberTaggingTool (switch number/suffix)") : tr("HouseNumberTaggingTool"),
    3344              "home-icon32",
    3445              tr("Launches the HouseNumberTaggingTool dialog"),
    35               Shortcut.registerShortcut("edit:housenumbertaggingtool", tr("Data: {0}", "HouseNumberTaggingTool"),
    36                 KeyEvent.VK_K, Shortcut.DIRECT),
     46              switchIncrement
     47                ? Shortcut.registerShortcut("edit:housenumbertaggingtool:switch",
     48                    tr("Data: {0}", tr("HouseNumberTaggingTool (switch number/suffix)")), KeyEvent.VK_K, Shortcut.SHIFT)
     49                : Shortcut.registerShortcut("edit:housenumbertaggingtool", tr("Data: {0}", "HouseNumberTaggingTool"),
     50                    KeyEvent.VK_K, Shortcut.DIRECT),
    3751              true);
    3852
    3953        this.pluginDir = pluginDir;
     54        this.switchIncrement = switchIncrement;
    4055        SelectionEventManager.getInstance().addSelectionListener(this);
    4156        setEnabled(false);
    4257    }
    … … public class LaunchAction extends JosmAction implements DataSelectionListener {  
    4964            return;
    5065        }
    5166     
    52         TagDialog dialog = new TagDialog(pluginDir, selection);
     67        TagDialog dialog = new TagDialog(pluginDir, selection, switchIncrement);
    5368        dialog.showDialog();
    5469    }
    5570
  • HouseNumberTaggingTool/src/org/openstreetmap/josm/plugins/housenumbertool/TagDialog.java

    diff --git a/HouseNumberTaggingTool/src/org/openstreetmap/josm/plugins/housenumbertool/TagDialog.java b/HouseNumberTaggingTool/src/org/openstreetmap/josm/plugins/housenumbertool/TagDialog.java
    index 7b9864a0f..917a44c58 100644
    a b import java.util.List;  
    2525import java.util.Set;
    2626import java.util.TreeSet;
    2727
     28import javax.swing.Box;
    2829import javax.swing.ButtonGroup;
    2930import javax.swing.JButton;
    3031import javax.swing.JCheckBox;
    … … public class TagDialog extends ExtendedDialog {  
    110111    private JComboBox<String> building;
    111112    private JRadioButton streetRadio;
    112113    private JRadioButton placeRadio;
     114    private JRadioButton incrementNumberRadio;
     115    private JRadioButton incrementSuffixRadio;
     116    private final boolean switchIncrement;
    113117
    114118    /**
    115119     * Constructs a new {@code TagDialog}.
    … … public class TagDialog extends ExtendedDialog {  
    117121     * @param selection selected primitive
    118122     */
    119123    public TagDialog(File pluginDir, OsmPrimitive selection) {
     124        this(pluginDir, selection, false);
     125    }
     126
     127    /**
     128     * Constructs a new {@code TagDialog}.
     129     * @param pluginDir plugin directory
     130     * @param selection selected primitive
     131     * @param switchIncrement if {@code true}, switch between incrementing the number and the suffix
     132     */
     133    public TagDialog(File pluginDir, OsmPrimitive selection, boolean switchIncrement) {
    120134        super(MainApplication.getMainFrame(), tr("House Number Editor"), new String[] {tr("OK"), tr("Cancel")}, true);
    121135        this.pluginDir = pluginDir;
    122136        this.selection = selection;
     137        this.switchIncrement = switchIncrement;
    123138
    124139        JPanel editPanel = createContentPane();
    125140
    126         setPreferredSize(new Dimension(900, 500));
    127         setMinimumSize(new Dimension(900, 500));
     141        setPreferredSize(new Dimension(900, 550));
     142        setMinimumSize(new Dimension(900, 550));
    128143
    129144        setContent(editPanel);
    130145        setButtonIcons("ok", "cancel");
    … … public class TagDialog extends ExtendedDialog {  
    283298        housenumberEnabled = generateCheckbox(TAG_ADDR_HOUSENUMBER, dto.isSaveHousenumber());
    284299        editPanel.add(housenumberEnabled, columnOne);
    285300
    286         housenumber = generateTextField(HouseNumberHelper.incrementHouseNumber(dto.getHousenumber(), dto.getHousenumberChangeValue()));
     301        String lastNumber = dto.getHousenumber();
     302        boolean incrementSuffix = dto.isIncrementSuffix();
     303        if (switchIncrement) {
     304            incrementSuffix = !HouseNumberHelper.hasSuffix(lastNumber);
     305            if (!incrementSuffix) {
     306                lastNumber = HouseNumberHelper.removeSuffix(lastNumber);
     307            }
     308        }
     309        if (incrementSuffix) {
     310            housenumber = generateTextField(HouseNumberHelper.incrementHouseNumberSuffix(lastNumber));
     311        } else {
     312            housenumber = generateTextField(HouseNumberHelper.incrementHouseNumber(lastNumber, dto.getHousenumberChangeValue()));
     313        }
    287314        housenumber.setEditable(true);
    288315
    289316        editPanel.add(housenumber, columnTwo);
    … … public class TagDialog extends ExtendedDialog {  
    291318        editPanel.add(generateAcceptButton(actionEvent -> housenumber.setText(selection.get(TAG_ADDR_HOUSENUMBER))), columnThree);
    292319        editPanel.add(generateTextField(selection.get(TAG_ADDR_HOUSENUMBER)), columnFour);
    293320
     321        // increment number or suffix
     322        incrementNumberRadio = new JRadioButton(tr("Increment number"));
     323        incrementNumberRadio.setSelected(!incrementSuffix);
     324
     325        incrementSuffixRadio = new JRadioButton(tr("Increment suffix"));
     326        incrementSuffixRadio.setToolTipText(tr("Increment letter or number suffixes, e.g. 1a or 1/1"));
     327        incrementSuffixRadio.setSelected(incrementSuffix);
     328
     329        ButtonGroup incrementGroup = new ButtonGroup();
     330        incrementGroup.add(incrementNumberRadio);
     331        incrementGroup.add(incrementSuffixRadio);
     332
     333        editPanel.add(Box.createHorizontalGlue(), GBC.std());
     334        editPanel.add(incrementNumberRadio, GBC.std().insets(5, 5, 0, 5));
     335        editPanel.add(incrementSuffixRadio, GBC.eol().insets(5, 5, 0, 5));
     336
    294337        // increment
    295338        JLabel seqLabel = new JLabel(tr("House number increment:"));
    296339        editPanel.add(seqLabel, columnOne);
    … … public class TagDialog extends ExtendedDialog {  
    410453            dto.setSaveStreet(streetEnabled.isSelected());
    411454            dto.setTagStreet(streetRadio.isSelected());
    412455            dto.setSaveSuburb(suburbEnabled.isSelected());
     456            dto.setIncrementSuffix(incrementSuffixRadio.isSelected());
    413457
    414458            dto.setBuilding((String) building.getSelectedItem());
    415459            dto.setSource(getAutoCompletingComboBoxValue(source));
  • HouseNumberTaggingTool/test/unit/org/openstreetmap/josm/plugins/housenumbertool/HouseNumberHelperTest.java

    diff --git a/HouseNumberTaggingTool/test/unit/org/openstreetmap/josm/plugins/housenumbertool/HouseNumberHelperTest.java b/HouseNumberTaggingTool/test/unit/org/openstreetmap/josm/plugins/housenumbertool/HouseNumberHelperTest.java
    index 5bee703c6..bb0941431 100644
    a b package org.openstreetmap.josm.plugins.housenumbertool;  
    33
    44
    55import static org.junit.jupiter.api.Assertions.assertEquals;
     6import static org.junit.jupiter.api.Assertions.assertFalse;
    67import static org.junit.jupiter.api.Assertions.assertNull;
     8import static org.junit.jupiter.api.Assertions.assertTrue;
    79
    810import org.junit.jupiter.api.Test;
    911
    … … class HouseNumberHelperTest {  
    2426        //assertEquals("۲", HouseNumberHelper.incrementHouseNumber("۱", 1)); // FIXME: how to increment persian numbers ?
    2527        assertEquals("2", HouseNumberHelper.incrementHouseNumber("۱", 1));
    2628        assertNull(HouseNumberHelper.incrementHouseNumber(null, 1));
     29        assertEquals("2/1", HouseNumberHelper.incrementHouseNumber("1/1", 1));
     30    }
     31
     32    /**
     33     * Unit test of {@link HouseNumberHelper#incrementHouseNumberSuffix}
     34     */
     35    @Test
     36    void testIncrementHouseNumberSuffix() {
     37        assertEquals("1a", HouseNumberHelper.incrementHouseNumberSuffix("1"));
     38        assertEquals("1b", HouseNumberHelper.incrementHouseNumberSuffix("1a"));
     39        assertEquals("1B", HouseNumberHelper.incrementHouseNumberSuffix("1A"));
     40        assertEquals("1-b", HouseNumberHelper.incrementHouseNumberSuffix("1-a"));
     41        assertEquals("1/2", HouseNumberHelper.incrementHouseNumberSuffix("1/1"));
     42        assertEquals("E1b", HouseNumberHelper.incrementHouseNumberSuffix("E1a"));
     43        assertNull(HouseNumberHelper.incrementHouseNumberSuffix(null));
     44    }
     45
     46    /**
     47     * Unit test of {@link HouseNumberHelper#hasSuffix} and {@link HouseNumberHelper#removeSuffix}
     48     */
     49    @Test
     50    void testRemoveSuffix() {
     51        assertFalse(HouseNumberHelper.hasSuffix("1"));
     52        assertFalse(HouseNumberHelper.hasSuffix("E1"));
     53        assertTrue(HouseNumberHelper.hasSuffix("1a"));
     54        assertTrue(HouseNumberHelper.hasSuffix("1/1"));
     55        assertFalse(HouseNumberHelper.hasSuffix(null));
     56        assertEquals("1", HouseNumberHelper.removeSuffix("1a"));
     57        assertEquals("1", HouseNumberHelper.removeSuffix("1-1"));
     58        assertEquals("E1", HouseNumberHelper.removeSuffix("E1a"));
    2759    }
    2860}