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

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

see #20129 - Fix typos and misspellings in the code (patch by gaben)

  • Property svn:eol-style set to native
File size: 6.4 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.osm.visitor;
3
4import java.util.HashMap;
5import java.util.List;
6import java.util.Map;
7import java.util.stream.Collectors;
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;
21import org.openstreetmap.josm.tools.Utils;
22
23/**
24 * MergeSourceBuildingVisitor helps to build the "hull" of a collection of {@link OsmPrimitive}s
25 * which shall be merged into another layer. The "hull" is slightly bigger than the original
26 * collection. It includes, for instance the nodes of a way in the original collection even though
27 * these nodes might not be present explicitly in the original collection. The "hull" also includes
28 * incomplete {@link OsmPrimitive}s which are referred to by relations in the original collection. And
29 * it turns {@link OsmPrimitive} referred to by {@link Relation}s in the original collection into
30 * incomplete {@link OsmPrimitive}s in the "hull", if they are not themselves present in the original collection.
31 * @since 1891
32 */
33public class MergeSourceBuildingVisitor implements OsmPrimitiveVisitor {
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.containsKey(primitive);
59 }
60
61 /**
62 * Remembers 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 = Utils.transform(w.getNodes(), n -> mappedPrimitives.get(n).getUniqueId());
82 clone.setNodeIds(newNodes);
83 mappedPrimitives.put(w, clone);
84 }
85
86 /**
87 * Remembers a relation in the hull
88 *
89 * @param r the relation
90 */
91 protected void rememberRelation(Relation r) {
92 RelationData clone;
93 if (isAlreadyRemembered(r)) {
94 clone = (RelationData) mappedPrimitives.get(r);
95 } else {
96 clone = r.save();
97 mappedPrimitives.put(r, clone);
98 }
99
100 clone.setMembers(r.getMembers().stream()
101 .map(m -> new RelationMemberData(m.getRole(), mappedPrimitives.get(m.getMember())))
102 .collect(Collectors.toList()));
103 }
104
105 protected void rememberRelationPartial(Relation r) {
106 if (isAlreadyRemembered(r))
107 return;
108 RelationData clone = r.save();
109 clone.getMembers().clear();
110 mappedPrimitives.put(r, clone);
111 }
112
113 protected void rememberIncomplete(OsmPrimitive primitive) {
114 if (isAlreadyRemembered(primitive))
115 return;
116 PrimitiveData clone = primitive.save();
117 clone.setIncomplete(true);
118 mappedPrimitives.put(primitive, clone);
119 }
120
121 @Override
122 public void visit(Node n) {
123 rememberNode(n);
124 }
125
126 @Override
127 public void visit(Way w) {
128 // remember all nodes this way refers to ...
129 for (Node n: w.getNodes()) {
130 n.accept(this);
131 }
132 // ... and the way itself
133 rememberWay(w);
134 }
135
136 @Override
137 public void visit(Relation r) {
138 // first, remember all primitives members refer to (only if necessary, see below)
139 rememberRelationPartial(r);
140 for (RelationMember member: r.getMembers()) {
141 if (isAlreadyRemembered(member.getMember())) {
142 // referred primitive already remembered
143 continue;
144 }
145 if (isInSelectionBase(member.getMember()) || member.getMember().isNew()) {
146 member.getMember().accept(this);
147 } else {
148 rememberIncomplete(member.getMember());
149 }
150 }
151 rememberRelation(r);
152 }
153
154 protected void buildHull() {
155 // Create all primitives first
156 for (PrimitiveData primitive: mappedPrimitives.values()) {
157 OsmPrimitive newPrimitive = hull.getPrimitiveById(primitive);
158 boolean created = newPrimitive == null;
159 if (created) {
160 newPrimitive = primitive.getType().newInstance(primitive.getUniqueId(), true);
161 }
162 if (newPrimitive instanceof Node && !primitive.isIncomplete()) {
163 newPrimitive.load(primitive);
164 }
165 if (created) {
166 hull.addPrimitive(newPrimitive);
167 }
168 }
169 // Then ways and relations
170 for (PrimitiveData primitive : mappedPrimitives.values()) {
171 if (!(primitive instanceof NodeData) && !primitive.isIncomplete()) {
172 hull.getPrimitiveById(primitive).load(primitive);
173 }
174 }
175 }
176
177 /**
178 * Builds and returns the "hull".
179 * @return the "hull" data set
180 */
181 public DataSet build() {
182 for (OsmPrimitive primitive: selectionBase.getAllSelected()) {
183 primitive.accept(this);
184 }
185 buildHull();
186 return hull;
187 }
188}
Note: See TracBrowser for help on using the repository browser.