Ignore:
Timestamp:
2005-10-27T00:38:03+02:00 (18 years ago)
Author:
imi
Message:
  • added commands to support undo later
  • added Edit-Layer concept
  • painting of deleted objects
File:
1 moved

Legend:

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

    r22 r23  
    1 package org.openstreetmap.josm.command;
     1package org.openstreetmap.josm.data.osm;
    22
    33import java.util.Collection;
    4 import java.util.Collections;
    54import java.util.HashMap;
    65import java.util.HashSet;
    7 import java.util.Iterator;
    86import java.util.LinkedList;
    97import java.util.Map;
     
    1210import org.openstreetmap.josm.data.Bounds;
    1311import org.openstreetmap.josm.data.SelectionTracker;
    14 import org.openstreetmap.josm.data.osm.LineSegment;
    15 import org.openstreetmap.josm.data.osm.Node;
    16 import org.openstreetmap.josm.data.osm.OsmPrimitive;
    17 import org.openstreetmap.josm.data.osm.Track;
     12import org.openstreetmap.josm.data.osm.visitor.AllNodesVisitor;
    1813
    1914/**
     
    4136         * are in this list but are in no track.
    4237         */
    43         Collection<LineSegment> pendingLineSegments = new LinkedList<LineSegment>();
     38        public Collection<LineSegment> pendingLineSegments = new LinkedList<LineSegment>();
    4439
    4540        /**
     
    5045         * track list.
    5146         */
    52         Collection<Track> tracks = new LinkedList<Track>();
    53 
    54         /**
    55          * Add the track to the tracklist.
    56          */
    57         public void addTrack(Track t) {
    58                 tracks.add(t);
    59         }
    60         /**
    61          * Remove the track from the tracklist.
    62          */
    63         public void removeTrack(Track t) {
    64                 t.destroy();
    65                 tracks.remove(t);
    66         }
    67         /**
    68          * Return a read-only collection of all tracks
    69          */
    70         public Collection<Track> tracks() {
    71                 return Collections.unmodifiableCollection(tracks);
    72         }
    73 
    74         /**
    75          * Add a newly created line segment to the pending lines list.
    76          */
    77         public void addPendingLineSegment(LineSegment ls) {
    78                 pendingLineSegments.add(ls);
    79         }
    80         /**
    81          * Remove a line segment from the pending lines list, because it has been
    82          * assigned to the track.
    83          * @param ls The line segment from the pending list
    84          * @param t The track, that will hold the line segment
    85          * @param end <code>true</code> to attach on the end. <code>false</code>
    86          *              to attach on the beginning.
    87          */
    88         public void assignPendingLineSegment(LineSegment ls, Track t, boolean end) {
    89                 pendingLineSegments.remove(ls);
    90                 if (end)
    91                         t.add(ls);
    92                 else
    93                         t.addStart(ls);
    94         }
    95         /**
    96          * Delete the pending line segment without moving it anywhere.
    97          */
    98         public void destroyPendingLineSegment(LineSegment ls) {
    99                 pendingLineSegments.remove(ls);
    100                 ls.destroy();
    101         }
    102         /**
    103          * Return an read-only iterator over all pending line segments.
    104          */
    105         public Collection<LineSegment> pendingLineSegments() {
    106                 return Collections.unmodifiableCollection(pendingLineSegments);
    107         }
    108 
     47        public Collection<Track> tracks = new LinkedList<Track>();
     48
     49       
     50        /**
     51         * This is a list of all back references of nodes to their track usage.
     52         */
     53        public Map<Node, Set<Track>> nodeTrackRef = new HashMap<Node, Set<Track>>();
     54        /**
     55         * This is a list of all back references of nodes to their line segments.
     56         */
     57        public Map<Node, Set<LineSegment>> nodeLsRef = new HashMap<Node, Set<LineSegment>>();
     58        /**
     59         * This is a list of all back references of lines to their tracks.
     60         */
     61        public Map<LineSegment, Set<Track>> lsTrackRef = new HashMap<LineSegment, Set<Track>>();
     62
     63        /**
     64         * Add a back reference from the node to the line segment.
     65         */
     66        public void addBackReference(Node from, LineSegment to) {
     67                Set<LineSegment> references = nodeLsRef.get(from);
     68                if (references == null)
     69                        references = new HashSet<LineSegment>();
     70                references.add(to);
     71                nodeLsRef.put(from, references);
     72        }
     73        /**
     74         * Add a back reference from the node to the track.
     75         */
     76        public void addBackReference(Node from, Track to) {
     77                Set<Track> references = nodeTrackRef.get(from);
     78                if (references == null)
     79                        references = new HashSet<Track>();
     80                references.add(to);
     81                nodeTrackRef.put(from, references);
     82        }
     83        /**
     84         * Add a back reference from the line segment to the track.
     85         */
     86        public void addBackReference(LineSegment from, Track to) {
     87                Set<Track> references = lsTrackRef.get(from);
     88                if (references == null)
     89                        references = new HashSet<Track>();
     90                references.add(to);
     91                lsTrackRef.put(from, references);
     92        }
     93
     94        /**
     95         * Removes all references to and from this line segment.
     96         */
     97        public void removeBackReference(LineSegment ls) {
     98                Set<LineSegment> s = nodeLsRef.get(ls.start);
     99                if (s != null)
     100                        s.remove(ls);
     101                s = nodeLsRef.get(ls.end);
     102                if (s != null)
     103                        s.remove(ls);
     104                lsTrackRef.remove(ls);
     105        }
     106        /**
     107         * Removes all references to and from the node.
     108         */
     109        public void removeBackReference(Node n) {
     110                nodeLsRef.remove(n);
     111                nodeTrackRef.remove(n);
     112        }
     113        /**
     114         * Removes all references to and from the track.
     115         */
     116        public void removeBackReference(Track t) {
     117                Collection<Node> nodes = AllNodesVisitor.getAllNodes(t);
     118                for (Node n : nodes) {
     119                        Set<Track> s = nodeTrackRef.get(n);
     120                        if (s != null)
     121                                s.remove(t);
     122                }
     123                for (LineSegment ls : t.segments) {
     124                        Set<Track> s = lsTrackRef.get(ls);
     125                        if (s != null)
     126                                s.remove(t);
     127                }
     128        }
     129       
     130        /**
     131         * Rebuild the caches of back references.
     132         */
     133        public void rebuildBackReferences() {
     134                nodeTrackRef.clear();
     135                nodeLsRef.clear();
     136                lsTrackRef.clear();
     137                for (Track t : tracks) {
     138                        for (LineSegment ls : t.segments) {
     139                                addBackReference(ls.start, ls);
     140                                addBackReference(ls.end, ls);
     141                                addBackReference(ls.start, t);
     142                                addBackReference(ls.end, t);
     143                                addBackReference(ls, t);
     144                        }
     145                }
     146                for (LineSegment ls : pendingLineSegments) {
     147                        addBackReference(ls.start, ls);
     148                        addBackReference(ls.end, ls);
     149                }
     150        }
     151       
    109152        /**
    110153         * Return the bounds of this DataSet, depending on X/Y values.
     
    177220                clearSelection(tracks);
    178221                for (Track t : tracks)
    179                         clearSelection(t.segments());
     222                        clearSelection(t.segments);
    180223        }
    181224
     
    190233                sel.addAll(getSelected(tracks));
    191234                for (Track t : tracks)
    192                         sel.addAll(getSelected(t.segments()));
     235                        sel.addAll(getSelected(t.segments));
    193236                return sel;
    194237        }
     
    198241         * The objects imported are not cloned, so from now on, these data belong
    199242         * to both datasets. So use mergeFrom only if you are about to abandon the
    200          * other dataset or this dataset.
     243         * other dataset.
     244         *
     245         * Elements are tried to merged.
     246         * Nodes are merged first, if their lat/lon are equal.
     247         * Line segments are merged, if they have the same nodes.
     248         * Tracs are merged, if they consist of the same line segments.
     249         *
     250         * Additional to that, every two objects with the same id are merged.
    201251         *
    202252         * @param ds    The DataSet to merge into this one.
    203          * @param mergeEqualNodes If <code>true</code>, nodes with the same lat/lon
    204          *              are merged together.
    205          */
    206         public void mergeFrom(DataSet ds, boolean mergeEqualNodes) {
    207                 if (mergeEqualNodes && !nodes.isEmpty()) {
    208                         Map<Node, Node> mergeMap = new HashMap<Node, Node>();
    209                         Set<Node> nodesToAdd = new HashSet<Node>();
    210                         for (Node n : nodes) {
    211                                 for (Iterator<Node> it = ds.nodes.iterator(); it.hasNext();) {
    212                                         Node dsn = it.next();
    213                                         if (n.coor.equalsLatLon(dsn.coor)) {
    214                                                 mergeMap.put(dsn, n);
    215                                                 n.mergeFrom(dsn);
    216                                                 it.remove();
    217                                         } else {
    218                                                 nodesToAdd.add(dsn);
    219                                         }
     253         * @return A list of all primitives that were used in the conjunction. That
     254         *              is all used primitives (the merged primitives and all added ones).
     255         */
     256        public Collection<OsmPrimitive> mergeFrom(DataSet ds) {
     257                Collection<OsmPrimitive> data = new LinkedList<OsmPrimitive>();
     258
     259                Set<LineSegment> myLineSegments = new HashSet<LineSegment>();
     260                myLineSegments.addAll(pendingLineSegments);
     261                for (Track t : tracks)
     262                        myLineSegments.addAll(t.segments);
     263               
     264                Set<LineSegment> otherLineSegments = new HashSet<LineSegment>();
     265                otherLineSegments.addAll(ds.pendingLineSegments);
     266                for (Track t : ds.tracks)
     267                        otherLineSegments.addAll(t.segments);
     268               
     269               
     270                // merge nodes
     271
     272                Map<Node, Node> nodeMap = new HashMap<Node, Node>();
     273                // find mergable
     274                for (Node otherNode : ds.nodes)
     275                        for (Node myNode : nodes)
     276                                if (otherNode.coor.equalsLatLon(myNode.coor))
     277                                        nodeMap.put(otherNode, myNode);
     278                // add
     279                data.addAll(new HashSet<Node>(nodeMap.values()));
     280                for (Node n : ds.nodes) {
     281                        if (!nodeMap.containsKey(n)) {
     282                                nodes.add(n);
     283                                data.add(n);
     284                        }
     285                }
     286                // reassign
     287                for (LineSegment ls : otherLineSegments) {
     288                        Node n = nodeMap.get(ls.start);
     289                        if (n != null)
     290                                ls.start = n;
     291                        n = nodeMap.get(ls.end);
     292                        if (n != null)
     293                                ls.end = n;
     294                }
     295
     296
     297                // merge line segments
     298
     299                Map<LineSegment, LineSegment> lsMap = new HashMap<LineSegment, LineSegment>();
     300                // find mergable
     301                for (LineSegment otherLS : otherLineSegments)
     302                        for (LineSegment myLS : myLineSegments)
     303                                if (otherLS.start == myLS.start && otherLS.end == myLS.end)
     304                                        lsMap.put(otherLS, myLS);
     305                // add pendings (ls from track are added later
     306                for (LineSegment ls : ds.pendingLineSegments) {
     307                        if (!lsMap.containsKey(ls)) {
     308                                pendingLineSegments.add(ls);
     309                                data.add(ls);
     310                        }
     311                }
     312                // reassign
     313                for (Track t : ds.tracks) {
     314                        for (int i = 0; i < t.segments.size(); ++i) {
     315                                LineSegment newLS = lsMap.get(t.segments.get(i));
     316                                if (newLS != null)
     317                                        t.segments.set(i, newLS);
     318                        }
     319                }
     320               
     321               
     322                // merge tracks
     323                LinkedList<Track> trackToAdd = new LinkedList<Track>();
     324                for (Track otherTrack : ds.tracks) {
     325                        boolean found = false;
     326                        for (Track myTrack : tracks) {
     327                                if (myTrack.segments.equals(otherTrack.segments)) {
     328                                        found = true;
     329                                        data.add(myTrack);
     330                                        break;
    220331                                }
    221332                        }
    222                         nodes.addAll(nodesToAdd);
    223                         for (Track t : ds.tracks) {
    224                                 for (LineSegment ls : t.segments()) {
    225                                         Node n = mergeMap.get(ls.getStart());
    226                                         if (n != null)
    227                                                 ls.start = n;
    228                                         n = mergeMap.get(ls.getEnd());
    229                                         if (n != null)
    230                                                 ls.end = n;
    231                                 }
    232                         }
    233                         tracks.addAll(ds.tracks);
    234                         for (LineSegment ls : ds.pendingLineSegments) {
    235                                 Node n = mergeMap.get(ls.getStart());
    236                                 if (n != null)
    237                                         ls.start = n;
    238                                 n = mergeMap.get(ls.getEnd());
    239                                 if (n != null)
    240                                         ls.end = n;
    241                         }
    242                         pendingLineSegments.addAll(ds.pendingLineSegments);
    243                 } else {
    244                         nodes.addAll(ds.nodes);
    245                         tracks.addAll(ds.tracks);
    246                         pendingLineSegments.addAll(ds.pendingLineSegments);
    247                 }
     333                        if (!found)
     334                                trackToAdd.add(otherTrack);
     335                }
     336                data.addAll(trackToAdd);
     337                tracks.addAll(trackToAdd);
     338
     339                rebuildBackReferences();
     340                return data;
    248341        }
    249342
Note: See TracChangeset for help on using the changeset viewer.