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

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

sonar - Immutable Field

  • 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 final DataSet selectionBase;
35 private final DataSet hull;
36 private final 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 * @throws IllegalArgumentException if selectionBase is null
45 */
46 public MergeSourceBuildingVisitor(DataSet selectionBase) {
47 CheckParameterUtil.ensureParameterNotNull(selectionBase, "selectionBase");
48 this.selectionBase = selectionBase;
49 this.hull = new DataSet();
50 this.mappedPrimitives = new HashMap<>();
51 }
52
53 protected boolean isInSelectionBase(OsmPrimitive primitive) {
54 return selectionBase.getAllSelected().contains(primitive);
55 }
56
57 protected boolean isAlreadyRemembered(OsmPrimitive primitive) {
58 return mappedPrimitives.keySet().contains(primitive);
59 }
60
61 /**
62 * Remebers a node in the "hull"
63 *
64 * @param n the node
65 */
66 protected void rememberNode(Node n) {
67 if (isAlreadyRemembered(n))
68 return;
69 mappedPrimitives.put(n, n.save());
70 }
71
72 /**
73 * remembers a way in the hull
74 *
75 * @param w the way
76 */
77 protected void rememberWay(Way w) {
78 if (isAlreadyRemembered(w))
79 return;
80 WayData clone = w.save();
81 List<Long> newNodes = new ArrayList<>(w.getNodesCount());
82 for (Node n: w.getNodes()) {
83 newNodes.add(mappedPrimitives.get(n).getUniqueId());
84 }
85 clone.setNodes(newNodes);
86 mappedPrimitives.put(w, clone);
87 }
88
89 /**
90 * Remembers a relation in the hull
91 *
92 * @param r the relation
93 */
94 protected void rememberRelation(Relation r) {
95 RelationData clone;
96 if (isAlreadyRemembered(r)) {
97 clone = (RelationData) mappedPrimitives.get(r);
98 } else {
99 clone = r.save();
100 mappedPrimitives.put(r, clone);
101 }
102
103 List<RelationMemberData> newMembers = new ArrayList<>();
104 for (RelationMember member: r.getMembers()) {
105 newMembers.add(
106 new RelationMemberData(member.getRole(), mappedPrimitives.get(member.getMember())));
107
108 }
109 clone.setMembers(newMembers);
110 }
111
112 protected void rememberRelationPartial(Relation r) {
113 if (isAlreadyRemembered(r))
114 return;
115 RelationData clone = r.save();
116 clone.getMembers().clear();
117 mappedPrimitives.put(r, clone);
118 }
119
120 protected void rememberIncomplete(OsmPrimitive primitive) {
121 if (isAlreadyRemembered(primitive))
122 return;
123 PrimitiveData clone = primitive.save();
124 clone.setIncomplete(true);
125 mappedPrimitives.put(primitive, clone);
126 }
127
128 @Override
129 public void visit(Node n) {
130 rememberNode(n);
131 }
132
133 @Override
134 public void visit(Way w) {
135 // remember all nodes this way refers to ...
136 //
137 for (Node n: w.getNodes()) {
138 n.accept(this);
139 }
140 // ... and the way itself
141 rememberWay(w);
142 }
143
144 @Override
145 public void visit(Relation r) {
146 // first, remember all primitives members refer to (only if necessary, see
147 // below)
148 //
149 rememberRelationPartial(r);
150 for (RelationMember member: r.getMembers()) {
151 if (isAlreadyRemembered(member.getMember())) {
152 // referred primitive already remembered
153 //
154 continue;
155 }
156 if (isInSelectionBase(member.getMember()) || member.getMember().isNew()) {
157 member.getMember().accept(this);
158 } else {
159 rememberIncomplete(member.getMember());
160 }
161 }
162 rememberRelation(r);
163 }
164
165 protected void buildHull() {
166 // Create all primitives first
167 for (PrimitiveData primitive: mappedPrimitives.values()) {
168 OsmPrimitive newPrimitive = hull.getPrimitiveById(primitive);
169 boolean created = newPrimitive == null;
170 if (created) {
171 newPrimitive = primitive.getType().newInstance(primitive.getUniqueId(), true);
172 }
173 if (newPrimitive instanceof Node && !primitive.isIncomplete()) {
174 newPrimitive.load(primitive);
175 }
176 if (created) {
177 hull.addPrimitive(newPrimitive);
178 }
179 }
180 // Then ways and relations
181 for (PrimitiveData primitive : mappedPrimitives.values()) {
182 if (!(primitive instanceof NodeData) && !primitive.isIncomplete()) {
183 hull.getPrimitiveById(primitive).load(primitive);
184 }
185 }
186 }
187
188 public DataSet build() {
189 for (OsmPrimitive primitive: selectionBase.getAllSelected()) {
190 primitive.accept(this);
191 }
192 buildHull();
193 return hull;
194 }
195}
Note: See TracBrowser for help on using the repository browser.