Ticket #17188: 17188_v4.patch

File 17188_v4.patch, 8.8 KB (added by reichg, 4 years ago)

put the imports back how they were (optimizing imports moved them around.)

  • src/org/openstreetmap/josm/data/validation/tests/Highways.java

     
    44import static org.openstreetmap.josm.data.validation.tests.CrossingWays.HIGHWAY;
    55import static org.openstreetmap.josm.tools.I18n.tr;
    66
     7import javax.swing.*;
     8import javax.swing.event.DocumentEvent;
     9import javax.swing.event.DocumentListener;
     10import java.awt.*;
     11import java.awt.event.ActionListener;
     12import java.text.DecimalFormat;
    713import java.util.ArrayList;
    814import java.util.Arrays;
    915import java.util.HashMap;
     
    1521import java.util.stream.Collectors;
    1622
    1723import org.openstreetmap.josm.command.ChangePropertyCommand;
     24import org.openstreetmap.josm.data.osm.BBox;
     25import org.openstreetmap.josm.data.osm.DataSet;
    1826import org.openstreetmap.josm.data.osm.Node;
    1927import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2028import org.openstreetmap.josm.data.osm.OsmUtils;
     
    2230import org.openstreetmap.josm.data.validation.Severity;
    2331import org.openstreetmap.josm.data.validation.Test;
    2432import org.openstreetmap.josm.data.validation.TestError;
     33import org.openstreetmap.josm.spi.preferences.Config;
     34import org.openstreetmap.josm.spi.preferences.IPreferences;
     35import org.openstreetmap.josm.tools.GBC;
    2536import org.openstreetmap.josm.tools.Logging;
    2637import org.openstreetmap.josm.tools.Utils;
    2738
     
    3849    protected static final int SOURCE_MAXSPEED_CONTEXT_MISMATCH_VS_MAXSPEED = 2705;
    3950    protected static final int SOURCE_MAXSPEED_CONTEXT_MISMATCH_VS_HIGHWAY = 2706;
    4051    protected static final int SOURCE_WRONG_LINK = 2707;
     52    protected static final int SOURCE_BUS_STOP_NEEDED = 2708;
    4153
    4254    protected static final String SOURCE_MAXSPEED = "source:maxspeed";
     55    protected static final String BUS = "bus";
     56    protected static final String PUBLIC_TRANSPORT = "public_transport";
    4357
     58    //Adding variables for #17188 : complain about bus stop position without nearby highway=bus_stop
     59    private final JFormattedTextField bboxExpansionConstant;
     60    private final JButton defaultButton;
     61    private final JLabel warningLabel;
     62    private final JLabel labelForBboxExpansion;
     63    private static final String BBOX_EXPANSION_PREF_KEY = "bboxExpansionConstant";
     64    private static final double EXPANSE_DISTANCE_DEFAULT = 0.00015;
     65    private final IPreferences preferences = Config.getPref();
     66
     67    //Create listeners for bboxExpansionConstant and defaultButton specifically
     68    private final ActionListener actionListener;
     69    private final DocumentListener documentListener;
     70
    4471    /**
    4572     * Classified highways in order of importance
    4673     */
     
    74101     */
    75102    public Highways() {
    76103        super(tr("Highways"), tr("Performs semantic checks on highways."));
     104
     105        // Variables for #17188
     106        bboxExpansionConstant = new JFormattedTextField(new DecimalFormat("#.########"));
     107        defaultButton = new JButton("Set Default (~15 meters)");
     108        warningLabel = new JLabel("Entry must be a valid number.");
     109        labelForBboxExpansion = new JLabel("Enter bbox expansion constant for searching nearby Nodes (LatLon degrees)");
     110
     111        //UI for #17188
     112        warningLabel.setVisible(false);
     113        warningLabel.setForeground(Color.RED);
     114
     115        //Listeners for #17188
     116        documentListener = new DocumentListener() {
     117            @Override
     118            public void insertUpdate(DocumentEvent e) {
     119                warn();
     120            }
     121
     122            @Override
     123            public void removeUpdate(DocumentEvent e) {
     124                warn();
     125            }
     126
     127            @Override
     128            public void changedUpdate(DocumentEvent e) {
     129                //unneeded for this listener's purpose.
     130            }
     131        };
     132        actionListener = e -> {
     133            bboxExpansionConstant.setValue(EXPANSE_DISTANCE_DEFAULT);
     134        };
    77135    }
    78136
    79137    @Override
     
    90148                // as maxspeed is not set on highways here but on signs, speed cameras, etc.
    91149                testSourceMaxspeed(n, false);
    92150            }
     151            if ((IN_DOWNLOADED_AREA.test(n) || n.isNew()) && n.hasTag(BUS, "yes") && n.hasTag(PUBLIC_TRANSPORT, "stop_position")) {
     152                // Test for 17188: complain about bus stop position without nearby highway=bus_stop
     153                testMissingBusStopNode(n);
     154            }
    93155        }
    94156    }
    95157
     
    243305        }
    244306    }
    245307
     308    /**
     309     * Tests for bus stop ("public_transport"="stop_position"/"bus"="yes") Nodes a long a way that are missing a related nearby Node with "highway=bus_stop"
     310     *
     311     * @param n Node being visited
     312     */
     313    public void testMissingBusStopNode(Node n) {
     314        int countOfNodesWithProperTags = 0;
     315        double expanseDistance = EXPANSE_DISTANCE_DEFAULT;
     316
     317        //Approximately 15 meters depending on Lat/Lon
     318        String expanseDistanceFromPrefs = preferences.get(BBOX_EXPANSION_PREF_KEY);
     319        if (expanseDistanceFromPrefs != null && !expanseDistanceFromPrefs.isEmpty()) {
     320            expanseDistance = Double.parseDouble(expanseDistanceFromPrefs);
     321        }
     322
     323        // Get nearby nodes within expanse distance
     324        List<Node> nearbyNodesWithinExpanseDistance = getNearbyNodesWithinShortDistance(n, expanseDistance);
     325        for (Node nearbyNodeWithinExpanseDistance : nearbyNodesWithinExpanseDistance) {
     326            if (nearbyNodeWithinExpanseDistance.hasTag(HIGHWAY, "bus_stop") && nearbyNodeWithinExpanseDistance.hasTag(BUS, "yes")) {
     327                countOfNodesWithProperTags += 1;
     328            }
     329        }
     330
     331        // If there are no nodes within expanse distance throw the error.
     332        if (countOfNodesWithProperTags == 0) {
     333            errors.add(TestError.builder(this, Severity.WARNING, SOURCE_BUS_STOP_NEEDED)
     334                    .message(tr("Node needs a nearby related Node with tags: {0} and {1}.",
     335                            "highway=bus_stop", "bus=yes"))
     336                    .primitives(n)
     337                    .build());
     338        }
     339    }
     340
     341    /**
     342     * Gathers list of Nodes within specified approximate distance (takes double but unit is LatLon degrees) of Node n.
     343     *
     344     * @param n               Node being visited
     345     * @param expanseDistance Distance to expand Node bounds. Units are in LatLon degrees.
     346     * @return List of Nodes
     347     */
     348    public List<Node> getNearbyNodesWithinShortDistance(Node n, double expanseDistance) {
     349        DataSet nodeDataSet = n.getDataSet();
     350
     351        // Expand bbox by expand distance
     352        BBox nodeBBox = n.getBBox();
     353        nodeBBox.addLatLon(nodeBBox.getCenter(), expanseDistance);
     354
     355        return nodeDataSet.searchNodes(nodeBBox);
     356    }
     357
    246358    private void handleCarWay(Node n, Way w) {
    247359        carsWays++;
    248360        if (!w.isFirstLastNode(n) || carsWays > 1) {
     
    295407            }
    296408        }
    297409    }
     410
     411    // Add UI for #17188
     412    @Override
     413    public void addGui(JPanel testPanel) {
     414        super.addGui(testPanel);
     415
     416        // Check if there is a valid preference set for expansion value
     417        String bboxExpansionPref = preferences.get(BBOX_EXPANSION_PREF_KEY);
     418        if (bboxExpansionPref != null && !bboxExpansionPref.isEmpty()) {
     419            try {
     420                Double.parseDouble(bboxExpansionPref);
     421                bboxExpansionConstant.setValue(Double.parseDouble(bboxExpansionPref));
     422            }
     423            catch (Exception exception) {
     424                bboxExpansionConstant.setValue(EXPANSE_DISTANCE_DEFAULT);
     425            }
     426        }
     427        else {
     428            bboxExpansionConstant.setValue(EXPANSE_DISTANCE_DEFAULT);
     429        }
     430
     431        bboxExpansionConstant.setColumns(5);
     432        bboxExpansionConstant.getDocument().addDocumentListener(documentListener);
     433        defaultButton.addActionListener(actionListener);
     434
     435        testPanel.add(labelForBboxExpansion, GBC.eol().insets(20,0,0,0));
     436        testPanel.add(bboxExpansionConstant, GBC.eol().insets(20, 0, 0, 0));
     437        testPanel.add(warningLabel, GBC.eol().insets(20,0,0,0));
     438        testPanel.add(defaultButton, GBC.eol().insets(20,0,0,0));
     439    }
     440
     441    /**
     442     * This is the logic checking if the input value from user is valid. If not the warning is displayed.
     443     */
     444    public void warn() {
     445        String expansionDegrees = bboxExpansionConstant.getText();
     446        try {
     447            Double.parseDouble(expansionDegrees);
     448            warningLabel.setVisible(false);
     449        }
     450        catch (Exception exception) {
     451            warningLabel.setVisible(true);
     452        }
     453    }
     454
     455    @Override
     456    public boolean ok() {
     457        //Uses most recent VALID entry for bbox expanse on OK
     458        preferences.put(BBOX_EXPANSION_PREF_KEY, bboxExpansionConstant.getValue().toString());
     459        return false;
     460    }
    298461}