Ignore:
Timestamp:
2007-12-01T18:25:53+01:00 (16 years ago)
Author:
gebner
Message:

Simplify the merge visitor.

File:
1 edited

Legend:

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

    r478 r479  
    5454        }
    5555
    56         /**
    57          * Merge the node if the id matches with any of the internal set or if
    58          * either id is zero, merge if lat/lon matches.
    59          */
     56        private <P extends OsmPrimitive> void genMerge(P other,
     57                        Collection<P> myprims, Collection<P> mergeprims,
     58                        HashMap<Long, P> primhash) {
     59                // 1. Try to find an identical prim with the same id.
     60                if (mergeAfterId(myprims, primhash, other))
     61                        return;
     62
     63                // 2. Try to find a prim we can merge with the prim from the other ds.
     64                for (P my : myprims) {
     65                        if (!mergeprims.contains(my)) { // This checks for id equality.
     66                                continue;
     67                        }
     68
     69                        if (match(my, other)) {
     70                                merged.put(other, my);
     71                                mergeCommon(my, other);
     72                                return;
     73                        }
     74                }
     75
     76                // 3. No idea how to merge that.  Simply add it unchanged.
     77                myprims.add(other);
     78        }
     79
    6080        public void visit(Node other) {
    61                 if (mergeAfterId(ds.nodes, nodeshash, other))
    62                         return;
    63 
    64                 Node my = null;
    65                 for (Node n : ds.nodes) {
    66                         if (match(n, other) && ((mergeds == null) || (!mergeds.nodes.contains(n)))) {
    67                                 my = n;
    68                                 break;
    69                         }
    70                 }
    71                 if (my == null)
    72                         ds.nodes.add(other);
    73                 else {
    74                         merged.put(other, my);
    75                         mergeCommon(my, other);
    76                         if (my.modified && !other.modified)
    77                                 return;
    78                         if (!my.coor.equalsEpsilon(other.coor)) {
    79                                 my.coor = other.coor;
    80                                 my.eastNorth = other.eastNorth;
    81                                 my.modified = other.modified;
    82                         }
    83                 }
    84         }
    85 
    86         /**
    87          * Merge the way if id matches or if all nodes match and the
    88          * id is zero of either way.
    89          */
     81                genMerge(other, ds.nodes, mergeds.nodes, nodeshash);
     82        }
     83
    9084        public void visit(Way other) {
    9185                fixWay(other);
    92                 if (mergeAfterId(ds.ways, wayshash, other))
    93                         return;
    94 
    95                 Way my = null;
    96                 for (Way w : ds.ways) {
    97                         if (match(other, w) && ((mergeds == null) || (!mergeds.ways.contains(w)))) {
    98                                 my = w;
    99                                 break;
    100                         }
    101                 }
    102                 if (my == null) {
    103                         ds.ways.add(other);
    104                 } else {
    105                         merged.put(other, my);
    106                         mergeCommon(my, other);
    107                         if (my.modified && !other.modified)
    108                                 return;
    109                         boolean same = true;
    110                         Iterator<Node> it = other.nodes.iterator();
    111                         for (Node n : my.nodes) {
    112                                 if (!match(n, it.next()))
    113                                         same = false;
    114                         }
    115                         if (!same) {
    116                                 my.modified = other.modified;
    117                         }
    118                 }
    119         }
    120 
    121         /**
    122          * Merge the relation if id matches or if all members match and the
    123          * id of either relation is zero.
    124          */
     86                genMerge(other, ds.ways, mergeds.ways, wayshash);
     87        }
     88
    12589        public void visit(Relation other) {
    12690                fixRelation(other);
    127                 if (mergeAfterId(ds.relations, relshash, other))
    128                         return;
    129 
    130                 Relation my = null;
    131                 for (Relation e : ds.relations) {
    132                         if (match(other, e) && ((mergeds == null) || (!mergeds.relations.contains(e)))) {
    133                                 my = e;
    134                                 break;
    135                         }
    136                 }
    137 
    138                 if (my == null) {
    139                         // Add the relation
    140                         ds.relations.add(other);
    141                 } else {
    142                         merged.put(other, my);
    143                         mergeCommon(my, other);
    144                         if (my.modified && !other.modified)
    145                                 return;
    146                         boolean same = true;
    147                         if (other.members.size() != my.members.size()) {
    148                                         same = false;
    149                         } else {
    150                                 for (RelationMember em : my.members) {
    151                                         if (!other.members.contains(em)) {
    152                                                 same = false;
    153                                                 break;
    154                                         }
    155                                 }
    156                         }
    157                         if (!same) {
    158                                 my.modified = other.modified;
    159                         }
    160                 }
     91                genMerge(other, ds.relations, mergeds.relations, relshash);
    16192        }
    16293
     
    210141        }
    211142
    212         /**
    213          * @return Whether the nodes match (in sense of "be mergable").
    214          */
    215         private boolean match(Node n1, Node n2) {
    216                 if (n1.id == 0 || n2.id == 0)
    217                         return n1.coor.equalsEpsilon(n2.coor);
    218                 return n1.id == n2.id;
    219         }
    220 
    221         /**
    222          * @return Whether the ways match (in sense of "be mergable").
    223          */
    224         private boolean match(Way w1, Way w2) {
    225                 if (w1.id == 0 || w2.id == 0) {
    226                         if (w1.nodes.size() != w2.nodes.size())
     143        private static <P extends OsmPrimitive> boolean match(P p1, P p2) {
     144                if (p1.id == 0 || p2.id == 0) {
     145                        return realMatch(p1, p2);
     146                }
     147                return p1.id == p2.id;
     148        }
     149
     150        /** @return true if the prims have pretty much the same data, i.e. the
     151         * same position, the same members, ...
     152         */
     153        // Java cannot dispatch on generics...
     154        private static boolean realMatch(OsmPrimitive p1, OsmPrimitive p2) {
     155                if (p1 instanceof Node && p2 instanceof Node) {
     156                        return realMatch((Node) p1, (Node) p2);
     157                } else if (p1 instanceof Way && p2 instanceof Way) {
     158                        return realMatch((Way) p1, (Way) p2);
     159                } else if (p1 instanceof Relation && p2 instanceof Relation) {
     160                        return realMatch((Relation) p1, (Relation) p2);
     161                } else {
     162                        throw new RuntimeException("arguments have unknown type");
     163                }
     164        }
     165
     166        private static boolean realMatch(Node n1, Node n2) {
     167                return n1.coor.equalsEpsilon(n2.coor);
     168        }
     169
     170        private static boolean realMatch(Way w1, Way w2) {
     171                if (w1.nodes.size() != w2.nodes.size())
    227172                        return false;
    228                         Iterator<Node> it = w1.nodes.iterator();
    229                         for (Node n : w2.nodes)
    230                                 if (!match(n, it.next()))
    231                                         return false;
    232                         return true;
    233                 }
    234                 return w1.id == w2.id;
    235         }
    236         /**
    237          * @return Whether the relations match (in sense of "be mergable").
    238          */
    239         private boolean match(Relation w1, Relation w2) {
     173                Iterator<Node> it = w1.nodes.iterator();
     174                for (Node n : w2.nodes)
     175                        if (!match(n, it.next()))
     176                                return false;
     177                return true;
     178        }
     179
     180        private static boolean realMatch(Relation w1, Relation w2) {
    240181                // FIXME this is not perfect yet...
    241                 if (w1.id == 0 || w2.id == 0) {
    242                         if (w1.members.size() != w2.members.size())
     182                if (w1.members.size() != w2.members.size())
     183                        return false;
     184                for (RelationMember em : w1.members) {
     185                        if (!w2.members.contains(em)) {
    243186                                return false;
    244                         for (RelationMember em : w1.members) {
    245                                 if (!w2.members.contains(em)) {
    246                                         return false;
    247                                 }
    248                         }
    249                         return true;
    250                 }
    251                 return w1.id == w2.id;
    252         }
    253 
     187                        }
     188                }
     189                return true;
     190        }
    254191
    255192        /**
Note: See TracChangeset for help on using the changeset viewer.