Changeset 57 in josm


Ignore:
Timestamp:
2006-02-21T13:39:40+01:00 (18 years ago)
Author:
imi
Message:

fixed bug where merged nodes and line segments were equal but not the same (aliasing)

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/org/openstreetmap/josm/data/osm/visitor/MergeVisitor.java

    r52 r57  
    11package org.openstreetmap.josm.data.osm.visitor;
    22
     3import java.util.HashMap;
    34import java.util.Iterator;
     5import java.util.LinkedList;
     6import java.util.Map;
    47
    58import org.openstreetmap.josm.data.osm.DataSet;
     
    2023        private final DataSet ds;
    2124       
     25        /**
     26         * A list of all nodes that got replaced with other nodes.
     27         * Key is the node in the other's dataset and the value is the one that is now
     28         * in ds.nodes instead.
     29         */
     30        private final Map<Node, Node> mergedNodes = new HashMap<Node, Node>();
     31        /**
     32         * A list of all line segments that got replaced with others.
     33         * Key is the segment in the other's dataset and the value is the one that is now
     34         * in ds.lineSegments.
     35         */
     36        private final Map<LineSegment, LineSegment> mergedLineSegments = new HashMap<LineSegment, LineSegment>();
     37       
    2238        public MergeVisitor(DataSet ds) {
    2339                this.ds = ds;
     
    3955                        ds.nodes.add(otherNode);
    4056                else {
     57                        mergedNodes.put(otherNode, myNode);
    4158                        mergeCommon(myNode, otherNode);
    4259                        if (myNode.modified && !otherNode.modified)
     
    6481                        ds.lineSegments.add(otherLs);
    6582                else {
     83                        mergedLineSegments.put(otherLs, myLs);
    6684                        mergeCommon(myLs, otherLs);
    6785                        if (myLs.modified && !otherLs.modified)
     
    99117                        Iterator<LineSegment> it = otherTrack.segments.iterator();
    100118                        for (LineSegment ls : myTrack.segments) {
    101                                 if (!match(ls, it.next())) {
     119                                if (!match(ls, it.next()))
    102120                                        same = false;
    103                                 }
    104121                        }
    105122                        if (!same) {
     
    113130        public void visit(Key k) {
    114131                //TODO: Key doesn't really fit the OsmPrimitive concept!
     132        }
     133       
     134        /**
     135         * Postprocess the dataset and fix all merged references to point to the actual
     136         * data.
     137         */
     138        public void fixReferences() {
     139                for (LineSegment ls : ds.lineSegments) {
     140                        if (mergedNodes.containsKey(ls.start))
     141                                ls.start = mergedNodes.get(ls.start);
     142                        if (mergedNodes.containsKey(ls.end))
     143                                ls.end = mergedNodes.get(ls.end);
     144                }
     145                for (Track t : ds.tracks) {
     146                        boolean replacedSomething = false;
     147                        LinkedList<LineSegment> newSegments = new LinkedList<LineSegment>();
     148                        for (LineSegment ls : t.segments) {
     149                                LineSegment otherLs = mergedLineSegments.get(ls);
     150                                newSegments.add(otherLs == null ? ls : otherLs);
     151                                if (otherLs != null)
     152                                        replacedSomething = true;
     153                        }
     154                        if (replacedSomething) {
     155                                t.segments.clear();
     156                                t.segments.addAll(newSegments);
     157                        }
     158                        for (LineSegment ls : t.segments) {
     159                                if (mergedNodes.containsKey(ls.start))
     160                                        ls.start = mergedNodes.get(ls.start);
     161                                if (mergedNodes.containsKey(ls.end))
     162                                        ls.end = mergedNodes.get(ls.end);
     163                        }
     164                }
    115165        }
    116166       
  • src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java

    r52 r57  
    136136                for (OsmPrimitive osm : ((OsmDataLayer)from).data.allPrimitives())
    137137                        osm.visit(visitor);
     138                visitor.fixReferences();
    138139        }
    139140
  • test/org/openstreetmap/josm/test/MergeVisitorTest.java

    r52 r57  
    77import org.openstreetmap.josm.data.osm.LineSegment;
    88import org.openstreetmap.josm.data.osm.Node;
     9import org.openstreetmap.josm.data.osm.OsmPrimitive;
    910import org.openstreetmap.josm.data.osm.visitor.MergeVisitor;
     11import org.openstreetmap.josm.test.framework.Bug;
    1012import org.openstreetmap.josm.test.framework.DataSetTestCaseHelper;
    1113
     
    1921        public void testMergeOldLineSegmentsWithNew() {
    2022                DataSet ds = new DataSet();
    21                 Node n1 = DataSetTestCaseHelper.createNode(ds);
    22                 n1.id = 1;
    23                 Node n2 = DataSetTestCaseHelper.createNode(ds);
    24                 n2.id = 2;
    25                 LineSegment ls1 = DataSetTestCaseHelper.createLineSegment(ds, n1, n2);
     23                Node[] n = createNodes(ds, 2);
     24                LineSegment ls1 = DataSetTestCaseHelper.createLineSegment(ds, n[0], n[1]);
    2625                ls1.id = 3;
    2726
    2827                Node newnode = new Node();
    29                 newnode.coor = new GeoPoint(n2.coor.lat, n2.coor.lon);
    30                 LineSegment newls = new LineSegment(n1, newnode);
     28                newnode.coor = new GeoPoint(n[1].coor.lat, n[1].coor.lon);
     29                LineSegment newls = new LineSegment(n[0], newnode);
    3130
    3231                MergeVisitor v = new MergeVisitor(ds);
     
    3433                assertEquals("line segment should have been merged.", 1, ds.lineSegments.size());
    3534        }
     35       
     36        /**
     37         * Nodes beeing merged are equal but not the same.
     38         */
     39        @Bug(54)
     40        public void testEqualNotSame() {
     41                // create a dataset with line segment a-b
     42                DataSet ds = new DataSet();
     43                Node n[] = createNodes(ds, 2);
     44                LineSegment ls1 = DataSetTestCaseHelper.createLineSegment(ds, n[0], n[1]);
     45                ls1.id = 1;
     46               
     47                // create an other dataset with line segment a'-c (a' is equal, but not same to a)
     48                DataSet ds2 = new DataSet();
     49                Node n2[] = createNodes(ds2, 2);
     50                n2[0].coor = new GeoPoint(n[0].coor.lat, n[0].coor.lon);
     51                n2[1].id = 42;
     52                LineSegment ls2 = DataSetTestCaseHelper.createLineSegment(ds, n2[0], n2[1]);
     53               
     54                MergeVisitor v = new MergeVisitor(ds);
     55                for (OsmPrimitive osm : ds2.allPrimitives())
     56                        osm.visit(v);
     57                v.fixReferences();
     58               
     59                assertSame(ls1.start, ls2.start);
     60        }
     61       
     62       
     63        /**
     64         * Create that amount of nodes and add them to the dataset. The id will be 1,2,3,4...
     65         * @param amount Number of nodes to create.
     66         * @return The created nodes.
     67         */
     68        private Node[] createNodes(DataSet ds, int amount) {
     69                Node[] nodes = new Node[amount];
     70                for (int i = 0; i < amount; ++i) {
     71                        nodes[i] = DataSetTestCaseHelper.createNode(ds);
     72                        nodes[i].id = i+1;
     73                }
     74                return nodes;
     75        }
    3676}
Note: See TracChangeset for help on using the changeset viewer.