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 = false;
99 checkTags: for (Tag wayTag : entity.getTags())
100 {
101 for (Tag wantedTag : this.wantedTags)
102 {
103 if (wayTag.getKey().equals(wantedTag.getKey()) && wayTag.getValue().equals(wantedTag.getValue()))
104 {
105 wanted = true;
106 break checkTags;
107 }
108 }
109 }
110 if (wanted)
111 {
112 Iterator<Tag> tagint = entity.getTags().iterator();
113 OSMWay osmWay = new OSMWay(entity.getId());
114 while (tagint.hasNext())
115 {
116 Tag waytag = tagint.next();
117 if (this.filterKeys.contains(waytag.getKey()) || this.filterKeys.isEmpty())
118 {
119 OSMTag tag = new OSMTag(waytag.getKey(), waytag.getValue());
120 osmWay.addTag(tag);
121 }
122 }
123 Iterator<WayNode> wayint1 = ((Way) entity).getWayNodes().iterator();
124 while (wayint1.hasNext())
125 {
126 WayNode waynode1 = wayint1.next();
127 osmWay.appendNode(waynode1.getNodeId());
128 }
129 this.net.addWay(osmWay);
130 }
131 }
132 else if (entity instanceof Relation)
133 {
134 boolean wanted = false;
135 checkTags: for (Tag entityTag : entity.getTags())
136 {
137 for (Tag wantedTag : this.wantedTags)
138 {
139 if (entityTag.getKey().equals(wantedTag.getKey()) && entityTag.getValue().equals(wantedTag.getValue()))
140 {
141 wanted = true;
142 break checkTags;
143 }
144 }
145 }
146 if (wanted)
147 {
148 Iterator<Tag> tagIterator = entity.getTags().iterator();
149 OSMRelation osmRelation = new OSMRelation(entity.getId());
150 while (tagIterator.hasNext())
151 {
152 Tag reltag = tagIterator.next();
153 if (this.filterKeys.contains(reltag.getKey()) || this.filterKeys.isEmpty())
154 {
155 OSMTag tag = new OSMTag(reltag.getKey(), reltag.getValue());
156 osmRelation.addTag(tag);
157 }
158 }
159 Iterator<RelationMember> relIterator = ((Relation) entity).getMembers().iterator();
160 while (relIterator.hasNext())
161 {
162 RelationMember relMember = relIterator.next();
163 if (relMember.getMemberType().equals(EntityType.Node))
164 {
165 osmRelation.addNode(relMember.getMemberId());
166 }
167 if (relMember.getMemberType().equals(EntityType.Way))
168 {
169 osmRelation.addWay(relMember.getMemberId());
170 }
171 }
172 this.net.addRelation(osmRelation);
173 }
174 }
175 }
176
177
178 @Override
179 public void close()
180 {
181
182 }
183
184
185 @Override
186 public final void complete()
187 {
188 HashMap<Long, OSMNode> usedNodes = new HashMap<Long, OSMNode>();
189 double total = this.net.getWays().size() + this.net.getRelations().size();
190 double counter = 0;
191 double percentageStep = 20.0d;
192 double nextPercentage = percentageStep;
193 this.progressListener.progress(new ProgressEvent(this, "Removing unused nodes"));
194 for (Long wid : this.net.getWays().keySet())
195 {
196 try
197 {
198 OSMWay w = this.net.getWay(wid);
199 for (Long nid : w.getNodes())
200 {
201 if (this.net.getNodes().containsKey(nid) && !usedNodes.containsKey(nid))
202 {
203 usedNodes.put(nid, this.net.getNode(nid));
204 }
205 }
206 }
207 catch (IOException e)
208 {
209 e.printStackTrace();
210 }
211 if (++counter / total * 100 >= nextPercentage)
212 {
213 this.progressListener.progress(new ProgressEvent(this, "Removing unused nodes " + nextPercentage + "%"));
214 nextPercentage += percentageStep;
215 }
216 }
217 for (OSMRelation r : this.net.getRelations().values())
218 {
219 try
220 {
221
222 for (Long nid : r.getNodes())
223 {
224 if (this.net.getNodes().containsKey(nid) && !usedNodes.containsKey(nid))
225 {
226 usedNodes.put(nid, this.net.getNode(nid));
227 }
228 }
229 }
230 catch (IOException e)
231 {
232 e.printStackTrace();
233 }
234 if (++counter / total * 100 >= nextPercentage)
235 {
236 this.progressListener.progress(new ProgressEvent(this, "Removing unused nodes " + nextPercentage + "%"));
237 nextPercentage += percentageStep;
238 }
239 }
240 this.net.setNodes(usedNodes);
241 this.progressListener.progress(new ProgressEvent(this, "Cleanup complete."));
242 }
243
244
245
246
247 public final OSMNetwork getNetwork()
248 {
249 return this.net;
250 }
251
252
253
254
255
256
257 public final void setWantedTags(final List<OSMTag> tags)
258 {
259 this.wantedTags = new ArrayList<Tag>();
260 for (OSMTag osmTag : tags)
261 {
262 this.wantedTags.add(new Tag(osmTag.getKey(), osmTag.getValue()));
263 }
264 }
265
266
267
268
269
270
271 public final void setFilterKeys(final List<String> keys)
272 {
273 this.filterKeys = keys;
274 }
275
276
277
278
279 public final ProgressListener getProgressListener()
280 {
281 return this.progressListener;
282 }
283
284
285
286
287 public final void setProgressListener(final ProgressListener progressListener)
288 {
289 this.progressListener = progressListener;
290 }
291
292
293 @Override
294 public String toString()
295 {
296 return "OSMParser [net=" + this.net + ", wantedTags=" + this.wantedTags + ", filterKeys=" + this.filterKeys + "]";
297 }
298 }