source: osm/applications/editors/josm/plugins/public_transport/src/public_transport/TrackReference.java@ 20772

Last change on this file since 20772 was 20772, checked in by roland, 14 years ago

Public Transport Plugin: Making UndoRedo possible

File size: 9.8 KB
Line 
1package public_transport;
2
3import static org.openstreetmap.josm.tools.I18n.marktr;
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.util.Iterator;
7import java.util.Vector;
8import javax.swing.JOptionPane;
9import javax.swing.event.TableModelEvent;
10import javax.swing.event.TableModelListener;
11
12import org.openstreetmap.josm.Main;
13import org.openstreetmap.josm.command.Command;
14import org.openstreetmap.josm.command.ChangeCommand;
15import org.openstreetmap.josm.command.DeleteCommand;
16import org.openstreetmap.josm.data.coor.LatLon;
17import org.openstreetmap.josm.data.gpx.GpxTrack;
18import org.openstreetmap.josm.data.gpx.GpxTrackSegment;
19import org.openstreetmap.josm.data.gpx.WayPoint;
20import org.openstreetmap.josm.data.osm.Node;
21
22public class TrackReference
23 implements Comparable< TrackReference >, TableModelListener
24{
25 public GpxTrack track;
26 public TrackStoplistTableModel stoplistTM;
27 public String stopwatchStart;
28 public String gpsStartTime;
29 public String gpsSyncTime;
30 public double timeWindow;
31 public double threshold;
32 private StopImporterAction controller = null;
33
34 public TrackReference(GpxTrack track, StopImporterAction controller)
35 {
36 this.track = track;
37 this.stoplistTM = new TrackStoplistTableModel(this);
38 this.stopwatchStart = "00:00:00";
39 this.gpsStartTime = null;
40 this.gpsSyncTime = null;
41 this.controller = controller;
42 if (track != null)
43 {
44 Iterator< GpxTrackSegment > siter = track.getSegments().iterator();
45 while ((siter.hasNext()) && (this.gpsSyncTime == null))
46 {
47 Iterator< WayPoint > witer = siter.next().getWayPoints().iterator();
48 if (witer.hasNext())
49 {
50 this.gpsStartTime = witer.next().getString("time");
51 if (this.gpsStartTime != null)
52 this.gpsSyncTime = this.gpsStartTime.substring(11, 19);
53 }
54 }
55 if (this.gpsSyncTime == null)
56 {
57 JOptionPane.showMessageDialog
58 (null, "The GPX file doesn't contain valid trackpoints. "
59 + "Please use a GPX file that has trackpoints.", "GPX File Trouble",
60 JOptionPane.ERROR_MESSAGE);
61
62 this.gpsStartTime = "1970-01-01T00:00:00Z";
63 this.gpsSyncTime = this.stopwatchStart;
64 }
65 }
66 else
67 this.gpsSyncTime = this.stopwatchStart;
68 this.timeWindow = 20;
69 this.threshold = 20;
70 }
71
72 public int compareTo(TrackReference tr)
73 {
74 String name = (String)track.getAttributes().get("name");
75 String tr_name = (String)tr.track.getAttributes().get("name");
76 if (name != null)
77 {
78 if (tr_name == null)
79 return -1;
80 return name.compareTo(tr_name);
81 }
82 return 1;
83 }
84
85 public String toString()
86 {
87 String buf = (String)track.getAttributes().get("name");
88 if (buf == null)
89 return "unnamed";
90 return buf;
91 }
92
93 public void tableChanged(TableModelEvent e)
94 {
95 if ((e.getType() == TableModelEvent.UPDATE) && (e.getFirstRow() >= 0))
96 {
97 double time = StopImporterDialog.parseTime
98 ((String)stoplistTM.getValueAt(e.getFirstRow(), 0));
99 if (time < 0)
100 {
101 JOptionPane.showMessageDialog
102 (null, "Can't parse a time from this string.", "Invalid value",
103 JOptionPane.ERROR_MESSAGE);
104 return;
105 }
106
107 LatLon latLon = computeCoor(time);
108
109 if (stoplistTM.nodes.elementAt(e.getFirstRow()) == null)
110 {
111 Node node = controller.createNode
112 (latLon, (String)stoplistTM.getValueAt(e.getFirstRow(), 1));
113 stoplistTM.nodes.set(e.getFirstRow(), node);
114 }
115 else
116 {
117 Node node = new Node(stoplistTM.nodes.elementAt(e.getFirstRow()));
118 node.setCoor(latLon);
119 node.put("name", (String)stoplistTM.getValueAt(e.getFirstRow(), 1));
120 Command cmd = new ChangeCommand(stoplistTM.nodes.elementAt(e.getFirstRow()), node);
121 if (cmd != null) {
122 Main.main.undoRedo.add(cmd);
123 }
124 }
125 }
126 }
127
128 public LatLon computeCoor(double time)
129 {
130 double gpsSyncTime = StopImporterDialog.parseTime(this.gpsSyncTime);
131 double dGpsStartTime = StopImporterDialog.parseTime(gpsStartTime);
132 if (gpsSyncTime < dGpsStartTime - 12*60*60)
133 gpsSyncTime += 24*60*60;
134 double timeDelta = gpsSyncTime - StopImporterDialog.parseTime(stopwatchStart);
135 time += timeDelta;
136
137 WayPoint wayPoint = null;
138 WayPoint lastWayPoint = null;
139 double wayPointTime = 0;
140 double lastWayPointTime = 0;
141 Iterator< GpxTrackSegment > siter = track.getSegments().iterator();
142 while (siter.hasNext())
143 {
144 Iterator< WayPoint > witer = siter.next().getWayPoints().iterator();
145 while (witer.hasNext())
146 {
147 wayPoint = witer.next();
148 String startTime = wayPoint.getString("time");
149 wayPointTime = StopImporterDialog.parseTime(startTime.substring(11, 19));
150 if (startTime.substring(11, 19).compareTo(gpsStartTime.substring(11, 19)) == -1)
151 wayPointTime += 24*60*60;
152 if (wayPointTime >= time)
153 break;
154 lastWayPoint = wayPoint;
155 lastWayPointTime = wayPointTime;
156 }
157 if (wayPointTime >= time)
158 break;
159 }
160
161 double lat = 0;
162 if ((wayPointTime == lastWayPointTime) || (lastWayPoint == null))
163 lat = wayPoint.getCoor().lat();
164 else
165 lat = wayPoint.getCoor().lat()
166 *(time - lastWayPointTime)/(wayPointTime - lastWayPointTime)
167 + lastWayPoint.getCoor().lat()
168 *(wayPointTime - time)/(wayPointTime - lastWayPointTime);
169 double lon = 0;
170 if ((wayPointTime == lastWayPointTime) || (lastWayPoint == null))
171 lon = wayPoint.getCoor().lon();
172 else
173 lon = wayPoint.getCoor().lon()
174 *(time - lastWayPointTime)/(wayPointTime - lastWayPointTime)
175 + lastWayPoint.getCoor().lon()
176 *(wayPointTime - time)/(wayPointTime - lastWayPointTime);
177
178 return new LatLon(lat, lon);
179 }
180
181 public void relocateNodes()
182 {
183 for (int i = 0; i < stoplistTM.nodes.size(); ++i)
184 {
185 Node node = stoplistTM.nodes.elementAt(i);
186 if (node == null)
187 continue;
188
189 double time = StopImporterDialog.parseTime
190 ((String)stoplistTM.getValueAt(i, 0));
191 LatLon latLon = computeCoor(time);
192
193 Node newNode = new Node(node);
194 newNode.setCoor(latLon);
195 Command cmd = new ChangeCommand(node, newNode);
196 if (cmd != null)
197 {
198 Main.main.undoRedo.add(cmd);
199 }
200 }
201 }
202
203 public void suggestStops()
204 {
205 Vector< WayPoint > wayPoints = new Vector< WayPoint >();
206 Iterator< GpxTrackSegment > siter = track.getSegments().iterator();
207 while (siter.hasNext())
208 {
209 Iterator< WayPoint > witer = siter.next().getWayPoints().iterator();
210 while (witer.hasNext())
211 wayPoints.add(witer.next());
212 }
213 Vector< Double > wayPointsDist = new Vector< Double >(wayPoints.size());
214
215 int i = 0;
216 double time = -48*60*60;
217 double dGpsStartTime = StopImporterDialog.parseTime(gpsStartTime);
218 while ((i < wayPoints.size()) && (time < dGpsStartTime + timeWindow/2))
219 {
220 if (wayPoints.elementAt(i).getString("time") != null)
221 time = StopImporterDialog.parseTime(wayPoints.elementAt(i)
222 .getString("time").substring(11,19));
223 if (time < dGpsStartTime)
224 time += 24*60*60;
225 wayPointsDist.add(Double.valueOf(Double.POSITIVE_INFINITY));
226 ++i;
227 }
228 while (i < wayPoints.size())
229 {
230 int j = i;
231 double time2 = time;
232 while ((j > 0) && (time - timeWindow/2 < time2))
233 {
234 --j;
235 if (wayPoints.elementAt(j).getString("time") != null)
236 time2 = StopImporterDialog.parseTime(wayPoints.elementAt(j)
237 .getString("time").substring(11,19));
238 if (time2 < dGpsStartTime)
239 time2 += 24*60*60;
240 }
241 int k = i + 1;
242 time2 = time;
243 while ((k < wayPoints.size()) && (time + timeWindow/2 > time2))
244 {
245 if (wayPoints.elementAt(k).getString("time") != null)
246 time2 = StopImporterDialog.parseTime(wayPoints.elementAt(k)
247 .getString("time").substring(11,19));
248 if (time2 < dGpsStartTime)
249 time2 += 24*60*60;
250 ++k;
251 }
252
253 if (j < k)
254 {
255 double dist = 0;
256 LatLon latLonI = wayPoints.elementAt(i).getCoor();
257 for (int l = j; l < k; ++l)
258 {
259 double distL = latLonI.greatCircleDistance(wayPoints.elementAt(l).getCoor());
260 if (distL > dist)
261 dist = distL;
262 }
263 wayPointsDist.add(Double.valueOf(dist));
264 }
265 else
266 wayPointsDist.add(Double.valueOf(Double.POSITIVE_INFINITY));
267
268 if (wayPoints.elementAt(i).getString("time") != null)
269 time = StopImporterDialog.parseTime(wayPoints.elementAt(i)
270 .getString("time").substring(11,19));
271 if (time < dGpsStartTime)
272 time += 24*60*60;
273 ++i;
274 }
275
276 Vector< Node > toDelete = new Vector< Node >();
277 for (i = 0; i < stoplistTM.getRowCount(); ++i)
278 {
279 if ((Node)stoplistTM.nodes.elementAt(i) != null)
280 toDelete.add((Node)stoplistTM.nodes.elementAt(i));
281 }
282 if (!toDelete.isEmpty())
283 {
284 Command cmd = DeleteCommand.delete
285 (Main.main.getEditLayer(), toDelete);
286 if (cmd == null)
287 return;
288 Main.main.undoRedo.add(cmd);
289 }
290 stoplistTM.clear();
291
292 LatLon lastStopCoor = null;
293 for (i = 1; i < wayPoints.size()-1; ++i)
294 {
295 if (wayPointsDist.elementAt(i).doubleValue() >= threshold)
296 continue;
297 if ((wayPointsDist.elementAt(i).compareTo(wayPointsDist.elementAt(i-1)) != -1)
298 || (wayPointsDist.elementAt(i).compareTo(wayPointsDist.elementAt(i+1)) != -1))
299 continue;
300
301 LatLon latLon = wayPoints.elementAt(i).getCoor();
302 if ((lastStopCoor != null) && (lastStopCoor.greatCircleDistance(latLon) < threshold))
303 continue;
304
305 if (wayPoints.elementAt(i).getString("time") != null)
306 {
307 time = StopImporterDialog.parseTime(wayPoints.elementAt(i)
308 .getString("time").substring(11,19));
309 double gpsSyncTime = StopImporterDialog.parseTime(this.gpsSyncTime);
310 if (gpsSyncTime < dGpsStartTime - 12*60*60)
311 gpsSyncTime += 24*60*60;
312 double timeDelta = gpsSyncTime - StopImporterDialog.parseTime(stopwatchStart);
313 time -= timeDelta;
314 stoplistTM.insertRow(-1, StopImporterAction.timeOf(time));
315 Node node = controller.createNode(latLon, "");
316 stoplistTM.nodes.set(stoplistTM.getRowCount()-1, node);
317 }
318
319 lastStopCoor = latLon;
320 }
321 }
322};
Note: See TracBrowser for help on using the repository browser.