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

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

sonar - fb-contrib:SPP_USE_CONTAINSKEY - Style - Method calls keySet() just to call contains, use containsKey instead

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