1 package org.opentrafficsim.road.network.factory.osm.input;
2
3 import java.io.IOException;
4 import java.io.Serializable;
5 import java.util.ArrayList;
6 import java.util.HashMap;
7 import java.util.Iterator;
8 import java.util.List;
9 import java.util.Map;
10
11 import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer;
12 import org.openstreetmap.osmosis.core.domain.v0_6.Entity;
13 import org.openstreetmap.osmosis.core.domain.v0_6.EntityType;
14 import org.openstreetmap.osmosis.core.domain.v0_6.Node;
15 import org.openstreetmap.osmosis.core.domain.v0_6.Relation;
16 import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember;
17 import org.openstreetmap.osmosis.core.domain.v0_6.Tag;
18 import org.openstreetmap.osmosis.core.domain.v0_6.Way;
19 import org.openstreetmap.osmosis.core.domain.v0_6.WayNode;
20 import org.openstreetmap.osmosis.core.task.v0_6.Sink;
21 import org.opentrafficsim.road.network.factory.osm.OSMNetwork;
22 import org.opentrafficsim.road.network.factory.osm.OSMNode;
23 import org.opentrafficsim.road.network.factory.osm.OSMRelation;
24 import org.opentrafficsim.road.network.factory.osm.OSMTag;
25 import org.opentrafficsim.road.network.factory.osm.OSMWay;
26 import org.opentrafficsim.road.network.factory.osm.events.ProgressEvent;
27 import org.opentrafficsim.road.network.factory.osm.events.ProgressListener;
28
29
30
31
32
33
34
35
36
37
38
39
40 public class OSMParser implements Sink, Serializable
41 {
42
43 private static final long serialVersionUID = 20141231L;
44
45
46 private OSMNetwork net = new OSMNetwork("tempnet");
47
48
49 private List<Tag> wantedTags;
50
51
52 private List<String> filterKeys;
53
54
55 private ProgressListener progressListener;
56
57
58
59
60
61
62 public OSMParser(final List<OSMTag> wantedTags, final List<String> filteredKeys)
63 {
64 setWantedTags(wantedTags);
65 this.filterKeys = filteredKeys;
66 }
67
68
69 @Override
70 public void initialize(final Map<String, Object> arg0)
71 {
72
73 }
74
75
76 @Override
77 public final void process(final EntityContainer entityContainer)
78 {
79 Entity entity = entityContainer.getEntity();
80 if (entity instanceof Node)
81 {
82 Node node = (Node) entity;
83 OSMNode osmNode = new OSMNode(entity.getId(), node.getLongitude(), node.getLatitude());
84 Iterator<Tag> tagint = entity.getTags().iterator();
85 while (tagint.hasNext())
86 {
87 Tag nodetag = tagint.next();
88 if (this.filterKeys.contains(nodetag.getKey()) || this.filterKeys.isEmpty())
89 {
90 OSMTag tag = new OSMTag(nodetag.getKey(), nodetag.getValue());
91 osmNode.addTag(tag);
92 }
93 }
94 this.net.addNode(osmNode);
95 }
96 else if (entity instanceof Way)
97 {
98 boolean wanted = this.wantedTags.size() == 0;
99 if (!wanted)
100 {
101 checkTags: for (Tag wayTag : entity.getTags())
102 {
103 for (Tag wantedTag : this.wantedTags)
104 {
105 if (wayTag.getKey().equals(wantedTag.getKey()) && wayTag.getValue().equals(wantedTag.getValue()))
106 {
107 wanted = true;
108 break checkTags;
109 }
110 }
111 }
112 }
113 if (wanted)
114 {
115 Iterator<Tag> tagint = entity.getTags().iterator();
116 OSMWay osmWay = new OSMWay(entity.getId());
117 while (tagint.hasNext())
118 {
119 Tag waytag = tagint.next();
120 if (this.filterKeys.contains(waytag.getKey()) || this.filterKeys.isEmpty())
121 {
122 OSMTag tag = new OSMTag(waytag.getKey(), waytag.getValue());
123 osmWay.addTag(tag);
124 }
125 }
126 Iterator<WayNode> wayint1 = ((Way) entity).getWayNodes().iterator();
127 while (wayint1.hasNext())
128 {
129 WayNode waynode1 = wayint1.next();
130 osmWay.appendNode(waynode1.getNodeId());
131 }
132 this.net.addWay(osmWay);
133 }
134 }
135 else if (entity instanceof Relation)
136 {
137 boolean wanted = false;
138 checkTags: for (Tag entityTag : entity.getTags())
139 {
140 for (Tag wantedTag : this.wantedTags)
141 {
142 if (entityTag.getKey().equals(wantedTag.getKey()) && entityTag.getValue().equals(wantedTag.getValue()))
143 {
144 wanted = true;
145 break checkTags;
146 }
147 }
148 }
149 if (wanted)
150 {
151 Iterator<Tag> tagIterator = entity.getTags().iterator();
152 OSMRelation osmRelation = new OSMRelation(entity.getId());
153 while (tagIterator.hasNext())
154 {
155 Tag reltag = tagIterator.next();
156 if (this.filterKeys.contains(reltag.getKey()) || this.filterKeys.isEmpty())
157 {
158 OSMTag tag = new OSMTag(reltag.getKey(), reltag.getValue());
159 osmRelation.addTag(tag);
160 }
161 }
162 Iterator<RelationMember> relIterator = ((Relation) entity).getMembers().iterator();
163 while (relIterator.hasNext())
164 {
165 RelationMember relMember = relIterator.next();
166 if (relMember.getMemberType().equals(EntityType.Node))
167 {
168 osmRelation.addNode(relMember.getMemberId());
169 }
170 if (relMember.getMemberType().equals(EntityType.Way))
171 {
172 osmRelation.addWay(relMember.getMemberId());
173 }
174 }
175 this.net.addRelation(osmRelation);
176 }
177 }
178 }
179
180
181 @Override
182 public void close()
183 {
184
185 }
186
187
188 @Override
189 public final void complete()
190 {
191 HashMap<Long, OSMNode> usedNodes = new HashMap<Long, OSMNode>();
192 double total = this.net.getWays().size() + this.net.getRelations().size();
193 double counter = 0;
194 double percentageStep = 20.0d;
195 double nextPercentage = percentageStep;
196 this.progressListener.progress(new ProgressEvent(this, "Removing unused nodes"));
197 for (Long wid : this.net.getWays().keySet())
198 {
199 try
200 {
201 OSMWay w = this.net.getWay(wid);
202 for (Long nid : w.getNodes())
203 {
204 if (this.net.getNodes().containsKey(nid) && !usedNodes.containsKey(nid))
205 {
206 usedNodes.put(nid, this.net.getNode(nid));
207 }
208 }
209 }
210 catch (IOException e)
211 {
212 e.printStackTrace();
213 }
214 if (++counter / total * 100 >= nextPercentage)
215 {
216 this.progressListener.progress(new ProgressEvent(this, "Removing unused nodes " + nextPercentage + "%"));
217 nextPercentage += percentageStep;
218 }
219 }
220 for (OSMRelation r : this.net.getRelations().values())
221 {
222 try
223 {
224
225 for (Long nid : r.getNodes())
226 {
227 if (this.net.getNodes().containsKey(nid) && !usedNodes.containsKey(nid))
228 {
229 usedNodes.put(nid, this.net.getNode(nid));
230 }
231 }
232 }
233 catch (IOException e)
234 {
235 e.printStackTrace();
236 }
237 if (++counter / total * 100 >= nextPercentage)
238 {
239 this.progressListener.progress(new ProgressEvent(this, "Removing unused nodes " + nextPercentage + "%"));
240 nextPercentage += percentageStep;
241 }
242 }
243 this.net.setNodes(usedNodes);
244 this.progressListener.progress(new ProgressEvent(this, "Cleanup complete."));
245 }
246
247
248
249
250 public final OSMNetwork getNetwork()
251 {
252 return this.net;
253 }
254
255
256
257
258
259
260 public final void setWantedTags(final List<OSMTag> tags)
261 {
262 this.wantedTags = new ArrayList<Tag>();
263 for (OSMTag osmTag : tags)
264 {
265 this.wantedTags.add(new Tag(osmTag.getKey(), osmTag.getValue()));
266 }
267 }
268
269
270
271
272
273
274 public final void setFilterKeys(final List<String> keys)
275 {
276 this.filterKeys = keys;
277 }
278
279
280
281
282 public final ProgressListener getProgressListener()
283 {
284 return this.progressListener;
285 }
286
287
288
289
290 public final void setProgressListener(final ProgressListener progressListener)
291 {
292 this.progressListener = progressListener;
293 }
294
295
296 @Override
297 public String toString()
298 {
299 return "OSMParser [net=" + this.net + ", wantedTags=" + this.wantedTags + ", filterKeys=" + this.filterKeys + "]";
300 }
301 }