Changeset 19226 in osm


Ignore:
Timestamp:
2009-12-28T12:53:26+01:00 (15 years ago)
Author:
guggis
Message:

'Fixed JOSM ticket #4231 - Validator: duplicate nodes test should round to OSM precision'

Location:
applications/editors/josm/plugins/validator
Files:
8 added
4 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/validator/build.xml

    r19224 r19226  
    2626          ** update before publishing
    2727        -->
    28         <property name="commit.message" value="Fixed JOSM ticket #4235 - Validation layer is not removed when data layers are removed" />
    29         <property name="plugin.main.version" value="2621" />
     28        <property name="commit.message" value="Fixed JOSM ticket  #4231 - Validator: duplicate nodes test should round to OSM precision" />
     29        <property name="plugin.main.version" value="2694" />
    3030
    3131
  • applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/ValidateUploadHook.java

    r18377 r19226  
    1515import org.openstreetmap.josm.actions.upload.UploadHook;
    1616import org.openstreetmap.josm.data.APIDataSet;
    17 import org.openstreetmap.josm.data.osm.DataSet;
    1817import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1918import org.openstreetmap.josm.plugins.validator.util.AgregatePrimitivesVisitor;
  • applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/ValidatorDialog.java

    r18928 r19226  
    4343import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    4444import org.openstreetmap.josm.io.OsmTransferException;
    45 import org.openstreetmap.josm.plugins.validator.tests.DuplicateNode;
    4645import org.openstreetmap.josm.tools.Shortcut;
    4746import org.xml.sax.SAXException;
  • applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/DuplicateNode.java

    r18928 r19226  
    44
    55import java.awt.geom.Area;
     6import java.util.ArrayList;
    67import java.util.Collection;
     8import java.util.HashMap;
     9import java.util.Iterator;
    710import java.util.LinkedHashSet;
    811import java.util.LinkedList;
    912import java.util.List;
    1013import java.util.Map;
     14import java.util.Map.Entry;
    1115
    1216import javax.swing.JOptionPane;
     
    3337    protected static int DUPLICATE_NODE = 1;
    3438
    35     /** Bag of all nodes */
    36     Bag<LatLon, OsmPrimitive> nodes;
     39    /** The map of potential duplicates.
     40     *
     41     * If there is exactly one node for a given pos, the map includes a pair <pos, Node>.
     42     * If there are multiple nodes for a given pos, the map includes a pair
     43     * <pos, NodesByEqualTagsMap> 
     44     */
     45    Map<LatLon,Object> potentialDuplicates;
    3746
    3847    /**
     
    4857    public void startTest(ProgressMonitor monitor) {
    4958        super.startTest(monitor);
    50         nodes = new Bag<LatLon, OsmPrimitive>(1000);
    51     }
    52 
     59        potentialDuplicates = new HashMap<LatLon, Object>();
     60    }
     61 
     62   
    5363        @Override
    54         public void endTest() {
    55                 for (List<OsmPrimitive> duplicated : nodes.values()) {
    56                         if (duplicated.size() > 1) {
    57                                 boolean sameTags = true;
    58                                 Map<String, String> keys0 = duplicated.get(0).getKeys();
    59                                 keys0.remove("created_by");
    60                                 for (int i = 0; i < duplicated.size(); i++) {
    61                                         Map<String, String> keysI = duplicated.get(i).getKeys();
    62                                         keysI.remove("created_by");
    63                                         if (!keys0.equals(keysI))
    64                                                 sameTags = false;
    65                                 }
    66                                 if (!sameTags) {
    67                                         TestError testError = new TestError(this, Severity.WARNING,
    68                                                         tr("Nodes at same position"), DUPLICATE_NODE,
    69                                                         duplicated);
    70                                         errors.add(testError);
    71                                 } else {
    72                                         TestError testError = new TestError(this, Severity.ERROR,
    73                                                         tr("Duplicated nodes"), DUPLICATE_NODE, duplicated);
    74                                         errors.add(testError);
    75                                 }
    76                         }
     64        public void endTest() {
     65                for (Entry<LatLon, Object> entry: potentialDuplicates.entrySet()) {
     66                        Object v = entry.getValue();
     67                        if (v instanceof Node) {
     68                                // just one node at this position. Nothing to report as
     69                                // error
     70                                continue;
     71                        }                       
     72                       
     73                        // multiple nodes at the same position -> report errors
     74                        //
     75                        NodesByEqualTagsMap map = (NodesByEqualTagsMap)v;
     76                        errors.addAll(map.buildTestErrors(this));
    7777                }
    7878                super.endTest();
    79                 nodes = null;
     79                potentialDuplicates = null;
    8080        }
    8181
    82     @Override
    83     public void visit(Node n)
    84     {
    85         if(n.isUsable())
    86             nodes.add(n.getCoor(), n);
    87     }
     82        @Override
     83        public void visit(Node n) {
     84                if (n.isUsable()) {
     85                        LatLon rounded = n.getCoor().getRoundedToOsmPrecision();
     86                        if (potentialDuplicates.get(rounded) == null) {         
     87                                // in most cases there is just one node at a given position. We
     88                                // avoid to create an extra object and add remember the node
     89                                // itself at this position
     90                                potentialDuplicates.put(rounded, n);
     91                        } else if (potentialDuplicates.get(rounded) instanceof Node) {
     92                                // we have an additional node at the same position. Create an extra
     93                                // object to keep track of the nodes at this position.
     94                                //
     95                                Node n1 = (Node)potentialDuplicates.get(rounded);
     96                                NodesByEqualTagsMap map = new NodesByEqualTagsMap();
     97                                map.add(n1);
     98                                map.add(n);
     99                                potentialDuplicates.put(rounded, map);
     100                        } else if (potentialDuplicates.get(rounded) instanceof NodesByEqualTagsMap) {
     101                                // we have multiple nodes at the same position.
     102                                //
     103                                NodesByEqualTagsMap map = (NodesByEqualTagsMap)potentialDuplicates.get(rounded);
     104                                map.add(n);
     105                        }                       
     106                }
     107        }
    88108
    89109    /**
     
    103123    }
    104124
    105     @Override
    106     public boolean isFixable(TestError testError)
    107     {
    108         return (testError.getTester() instanceof DuplicateNode);
    109     }
     125        @Override
     126        public boolean isFixable(TestError testError) {
     127                return (testError.getTester() instanceof DuplicateNode);
     128        }
    110129
    111130    /**
     
    138157        return true;
    139158    }
     159   
     160    static private class NodesByEqualTagsMap {
     161        /**
     162         * a bag of primitives with the same position. The bag key is represented
     163         * by the tag set of the primitive. This allows for easily find nodes at
     164         * the same position with the same tag sets later.
     165         */
     166        private Bag<Map<String,String>, OsmPrimitive> bag;
     167
     168        public NodesByEqualTagsMap() {
     169                bag = new Bag<Map<String,String>, OsmPrimitive>();
     170        }
     171       
     172        public void add(Node n) {
     173                bag.add(n.getKeys(), n);
     174        }
     175               
     176        public List<TestError> buildTestErrors(Test parentTest) {
     177                List<TestError> errors = new ArrayList<TestError>();
     178                // check whether we have multiple nodes at the same position with
     179                // the same tag set
     180                //             
     181                for (Iterator<Map<String,String>> it = bag.keySet().iterator(); it.hasNext(); ) {
     182                        Map<String,String> tagSet = it.next();
     183                        if (bag.get(tagSet).size() > 1) {
     184                                errors.add(new TestError(
     185                                                parentTest,
     186                                                Severity.ERROR,
     187                                                tr("Duplicated nodes"),
     188                                                DUPLICATE_NODE,
     189                                                bag.get(tagSet)
     190                                ));
     191                                it.remove();
     192                        }
     193                       
     194                }
     195               
     196                // check whether we have multiple nodes at the same position with
     197                // differing tag sets
     198                //
     199                if (!bag.isEmpty()) {
     200                        List<OsmPrimitive> duplicates = new ArrayList<OsmPrimitive>();
     201                        for (List<OsmPrimitive> l: bag.values()) {
     202                                duplicates.addAll(l);
     203                        }
     204                        if (duplicates.size() > 1) {
     205                                errors.add(new TestError(
     206                                                parentTest,
     207                                                Severity.WARNING,
     208                                                        tr("Nodes at same position"),
     209                                                        DUPLICATE_NODE,
     210                                                        duplicates
     211                                        ));
     212                        }
     213                }
     214                return errors;
     215        }       
     216    }
    140217}
Note: See TracChangeset for help on using the changeset viewer.