source: josm/trunk/src/org/openstreetmap/josm/data/osm/visitor/MergeSourceBuildingVisitor.java@ 7005

Last change on this file since 7005 was 7005, checked in by Don-vip, 10 years ago

see #8465 - use diamond operator where applicable

  • Property svn:eol-style set to native
File size: 6.5 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.osm.visitor;
3
4import java.util.ArrayList;
5import java.util.HashMap;
6import java.util.List;
7import java.util.Map;
8
9import org.openstreetmap.josm.data.osm.DataSet;
10import org.openstreetmap.josm.data.osm.Node;
11import org.openstreetmap.josm.data.osm.NodeData;
12import org.openstreetmap.josm.data.osm.OsmPrimitive;
13import org.openstreetmap.josm.data.osm.PrimitiveData;
14import org.openstreetmap.josm.data.osm.Relation;
15import org.openstreetmap.josm.data.osm.RelationData;
16import org.openstreetmap.josm.data.osm.RelationMember;
17import org.openstreetmap.josm.data.osm.RelationMemberData;
18import org.openstreetmap.josm.data.osm.Way;
19import org.openstreetmap.josm.data.osm.WayData;
20import org.openstreetmap.josm.tools.CheckParameterUtil;
21
22/**
23 * MergeSourceBuildingVisitor helps to build the "hull" of a collection of {@link OsmPrimitive}s
24 * which shall be merged into another layer. The "hull" is slightly bigger than the original
25 * collection. It includes, for instance the nodes of a way in the original collection even though
26 * these nodes might not be present explicitly in the original collection. The "hull" also includes
27 * incomplete {@link OsmPrimitive}s which are referred to by relations in the original collection. And
28 * it turns {@link OsmPrimitive} referred to by {@link Relation}s in the original collection into
29 * incomplete {@link OsmPrimitive}s in the "hull", if they are not themselves present in the
30 * original collection.
31 *
32 */
33public class MergeSourceBuildingVisitor extends AbstractVisitor {
34 private DataSet selectionBase;
35 private DataSet hull;
36 private Map<OsmPrimitive, PrimitiveData> mappedPrimitives;
37
38 /**
39 * Creates the visitor. The visitor starts to build the "hull" from
40 * the currently selected primitives in the dataset <code>selectionBase</code>,
41 * i.e. from {@link DataSet#getSelected()}.
42 *
43 * @param selectionBase the dataset. Must not be null.
44 * @exception IllegalArgumentException thrown if selectionBase is null
45 *
46 */
47 public MergeSourceBuildingVisitor(DataSet selectionBase) throws IllegalArgumentException {
48 CheckParameterUtil.ensureParameterNotNull(selectionBase, "selectionBase");
49 this.selectionBase = selectionBase;
50 this.hull = new DataSet();
51 this.mappedPrimitives = new HashMap<>();
52 }
53
54 protected boolean isInSelectionBase(OsmPrimitive primitive) {
55 return selectionBase.getAllSelected().contains(primitive);
56 }
57
58 protected boolean isAlreadyRemembered(OsmPrimitive primitive) {
59 return mappedPrimitives.keySet().contains(primitive);
60 }
61
62 /**
63 * Remebers a node in the "hull"
64 *
65 * @param n the node
66 */
67 protected void rememberNode(Node n) {
68 if (isAlreadyRemembered(n))
69 return;
70 mappedPrimitives.put(n, n.save());
71 }
72
73 /**
74 * remembers a way in the hull
75 *
76 * @param w the way
77 */
78 protected void rememberWay(Way w) {
79 if (isAlreadyRemembered(w))
80 return;
81 WayData clone = w.save();
82 List<Long> newNodes = new ArrayList<>(w.getNodesCount());
83 for (Node n: w.getNodes()) {
84 newNodes.add(mappedPrimitives.get(n).getUniqueId());
85 }
86 clone.setNodes(newNodes);
87 mappedPrimitives.put(w, clone);
88 }
89
90 /**
91 * Remembers a relation in the hull
92 *
93 * @param r the relation
94 */
95 protected void rememberRelation(Relation r) {
96 RelationData clone;
97 if (isAlreadyRemembered(r)) {
98 clone = (RelationData)mappedPrimitives.get(r);
99 } else {
100 clone = r.save();
101 mappedPrimitives.put(r, clone);
102 }
103
104 List<RelationMemberData> newMembers = new ArrayList<>();
105 for (RelationMember member: r.getMembers()) {
106 newMembers.add(
107 new RelationMemberData(member.getRole(), mappedPrimitives.get(member.getMember())));
108
109 }
110 clone.setMembers(newMembers);
111 }
112
113 protected void rememberRelationPartial(Relation r) {
114 if (isAlreadyRemembered(r))
115 return;
116 RelationData clone = r.save();
117 clone.getMembers().clear();
118 mappedPrimitives.put(r, clone);
119 }
120
121 protected void rememberIncomplete(OsmPrimitive primitive) {
122 if (isAlreadyRemembered(primitive))
123 return;
124 PrimitiveData clone = primitive.save();
125 clone.setIncomplete(true);
126 mappedPrimitives.put(primitive, clone);
127 }
128
129 @Override
130 public void visit(Node n) {
131 rememberNode(n);
132 }
133
134 @Override
135 public void visit(Way w) {
136 // remember all nodes this way refers to ...
137 //
138 for (Node n: w.getNodes()) {
139 n.accept(this);
140 }
141 // ... and the way itself
142 rememberWay(w);
143 }
144
145 @Override
146 public void visit(Relation r) {
147 // first, remember all primitives members refer to (only if necessary, see
148 // below)
149 //
150 rememberRelationPartial(r);
151 for (RelationMember member: r.getMembers()) {
152 if (isAlreadyRemembered(member.getMember())) {
153 // referred primitive already remembered
154 //
155 continue;
156 }
157 if (isInSelectionBase(member.getMember()) || member.getMember().isNew()) {
158 member.getMember().accept(this);
159 } else {
160 rememberIncomplete(member.getMember());
161 }
162 }
163 rememberRelation(r);
164 }
165
166 protected void buildHull() {
167 // Create all primitives first
168 for (PrimitiveData primitive: mappedPrimitives.values()) {
169 OsmPrimitive newPrimitive = hull.getPrimitiveById(primitive);
170 boolean created = newPrimitive == null;
171 if (created) {
172 newPrimitive = primitive.getType().newInstance(primitive.getUniqueId(), true);
173 }
174 if (newPrimitive instanceof Node && !primitive.isIncomplete()) {
175 newPrimitive.load(primitive);
176 }
177 if (created) {
178 hull.addPrimitive(newPrimitive);
179 }
180 }
181 // Then ways and relations
182 for (PrimitiveData primitive : mappedPrimitives.values()) {
183 if (!(primitive instanceof NodeData) && !primitive.isIncomplete()) {
184 hull.getPrimitiveById(primitive).load(primitive);
185 }
186 }
187 }
188
189 public DataSet build() {
190 for (OsmPrimitive primitive: selectionBase.getAllSelected()) {
191 primitive.accept(this);
192 }
193 buildHull();
194 return hull;
195 }
196}
Note: See TracBrowser for help on using the repository browser.