1 | // License: GPL. For details, see LICENSE file.
|
---|
2 | package org.openstreetmap.josm.io;
|
---|
3 |
|
---|
4 | import java.io.File;
|
---|
5 | import java.util.ArrayList;
|
---|
6 | import java.util.Collection;
|
---|
7 |
|
---|
8 | import javax.xml.bind.JAXBContext;
|
---|
9 | import javax.xml.bind.JAXBElement;
|
---|
10 | import javax.xml.bind.JAXBException;
|
---|
11 | import javax.xml.bind.Unmarshaller;
|
---|
12 | import javax.xml.datatype.XMLGregorianCalendar;
|
---|
13 |
|
---|
14 | import org.openstreetmap.josm.data.coor.LatLon;
|
---|
15 | import org.openstreetmap.josm.data.gpx.GpxData;
|
---|
16 | import org.openstreetmap.josm.data.gpx.GpxTrack;
|
---|
17 | import org.openstreetmap.josm.data.gpx.WayPoint;
|
---|
18 | import org.openstreetmap.josm.io.tcx.ActivityLapT;
|
---|
19 | import org.openstreetmap.josm.io.tcx.ActivityT;
|
---|
20 | import org.openstreetmap.josm.io.tcx.CourseT;
|
---|
21 | import org.openstreetmap.josm.io.tcx.PositionT;
|
---|
22 | import org.openstreetmap.josm.io.tcx.TrackT;
|
---|
23 | import org.openstreetmap.josm.io.tcx.TrackpointT;
|
---|
24 | import org.openstreetmap.josm.io.tcx.TrainingCenterDatabaseT;
|
---|
25 |
|
---|
26 | /**
|
---|
27 | * TCX Reader. This class is based on code genarated by the Java Architecture
|
---|
28 | * for XML Binding (JAXB). For this class to work you will need the API und IMPL
|
---|
29 | * Jars from the RI. JAXB can be downloaded at <a
|
---|
30 | * href="https://jaxb.dev.java.net/">https://jaxb.dev.java.net/</a>. This class
|
---|
31 | * has been developed using JAXB version 2.1.7.
|
---|
32 | * <p>
|
---|
33 | * Additional information and tutorial are available at: <a
|
---|
34 | * href="http://java.sun.com/developer/technicalArticles/WebServices/jaxb/">http://java.sun.com/developer/technicalArticles/WebServices/jaxb/</a>
|
---|
35 | * <p>
|
---|
36 | * The Garmin TCX Schema file can be downloaded from: <a
|
---|
37 | * href="http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd">http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd</a>
|
---|
38 | * The command used to generate the code is: <code>
|
---|
39 | * xjc.bat -p org.openstreetmap.josm.io.tcx TrainingCenterDatabasev2.xsd -d <path to the src folder of JOSM>
|
---|
40 | * </code>
|
---|
41 | * <p>
|
---|
42 | * Note: if you get an exception that JAXB 2.1 is not supported on your system, you will have to add the jaxb-api.jar
|
---|
43 | * to the endorsed directory (create it if necessary) of your JRE. Usually it is something like this:
|
---|
44 | * \<program files>\Java\jre<java version>\lib\endorsed
|
---|
45 | *
|
---|
46 | * @author adrian <as@nitegate.de>
|
---|
47 | *
|
---|
48 | */
|
---|
49 | public class TcxReader {
|
---|
50 |
|
---|
51 | private File tcxFile;
|
---|
52 |
|
---|
53 | private GpxData gpxData;
|
---|
54 |
|
---|
55 | /**
|
---|
56 | * @param tcxFile
|
---|
57 | */
|
---|
58 | public TcxReader(File tcxFile) {
|
---|
59 | super();
|
---|
60 | this.tcxFile = tcxFile;
|
---|
61 | parseFile();
|
---|
62 | }
|
---|
63 |
|
---|
64 | /**
|
---|
65 | *
|
---|
66 | */
|
---|
67 | @SuppressWarnings("unchecked") private void parseFile() {
|
---|
68 | try {
|
---|
69 | JAXBContext jc = JAXBContext
|
---|
70 | .newInstance(TrainingCenterDatabaseT.class);
|
---|
71 | Unmarshaller unmarshaller = jc.createUnmarshaller();
|
---|
72 | JAXBElement<TrainingCenterDatabaseT> element = (JAXBElement<TrainingCenterDatabaseT>)unmarshaller
|
---|
73 | .unmarshal(tcxFile);
|
---|
74 |
|
---|
75 | TrainingCenterDatabaseT tcd = element.getValue();
|
---|
76 |
|
---|
77 | gpxData = new GpxData();
|
---|
78 |
|
---|
79 | // Usually logged activities are in the activities tag.
|
---|
80 | parseDataFromActivities(tcd);
|
---|
81 | // GPS tracks in the course tag are generated by the user.
|
---|
82 | // Maybe not a good idea to import them.
|
---|
83 | parseDataFromCourses(tcd);
|
---|
84 |
|
---|
85 | } catch (JAXBException e) {
|
---|
86 | throw new RuntimeException(e);
|
---|
87 | }
|
---|
88 | }
|
---|
89 |
|
---|
90 | /** Convert a TrackpointT to a WayPoint.
|
---|
91 | * @param tp TrackpointT to convert
|
---|
92 | * @return tp converted to WayPoint, or null
|
---|
93 | */
|
---|
94 | private static WayPoint convertPoint(TrackpointT tp) {
|
---|
95 |
|
---|
96 | PositionT p = tp.getPosition();
|
---|
97 |
|
---|
98 | if (p == null) {
|
---|
99 | // If the TrackPointT lacks a position, return null.
|
---|
100 | return null;
|
---|
101 | }
|
---|
102 |
|
---|
103 | WayPoint waypt = new WayPoint(new LatLon(p.getLatitudeDegrees(),
|
---|
104 | p.getLongitudeDegrees()));
|
---|
105 | // If WayPoint handled elevation data, we could get it from
|
---|
106 | // tp.getAltitudeMeters().
|
---|
107 |
|
---|
108 | XMLGregorianCalendar time = tp.getTime();
|
---|
109 |
|
---|
110 | if (time != null) {
|
---|
111 | waypt.time = .001 * time.toGregorianCalendar().getTimeInMillis();
|
---|
112 | }
|
---|
113 |
|
---|
114 | return waypt;
|
---|
115 | }
|
---|
116 |
|
---|
117 | /**
|
---|
118 | * @param tcd
|
---|
119 | */
|
---|
120 | private void parseDataFromActivities(TrainingCenterDatabaseT tcd) {
|
---|
121 | if ((tcd.getActivities() != null)
|
---|
122 | && (tcd.getActivities().getActivity() != null)) {
|
---|
123 | for (ActivityT activity : tcd.getActivities().getActivity()) {
|
---|
124 | if (activity.getLap() != null) {
|
---|
125 | for (ActivityLapT activityLap : activity.getLap()) {
|
---|
126 | if (activityLap.getTrack() != null) {
|
---|
127 | XMLGregorianCalendar startTime = activityLap
|
---|
128 | .getStartTime();
|
---|
129 | GpxTrack currentTrack = new GpxTrack();
|
---|
130 | gpxData.tracks.add(currentTrack);
|
---|
131 | for (TrackT track : activityLap.getTrack()) {
|
---|
132 | if (track.getTrackpoint() != null) {
|
---|
133 | Collection<WayPoint> currentTrackSeg = new ArrayList<WayPoint>();
|
---|
134 | currentTrack.trackSegs.add(currentTrackSeg);
|
---|
135 | for (TrackpointT tp :
|
---|
136 | track.getTrackpoint()) {
|
---|
137 | WayPoint waypt = convertPoint(tp);
|
---|
138 |
|
---|
139 | if (waypt != null) {
|
---|
140 | if (startTime != null) {
|
---|
141 | waypt.attr.put("name",
|
---|
142 | startTime
|
---|
143 | .toString());
|
---|
144 | startTime = null;
|
---|
145 | }
|
---|
146 |
|
---|
147 | currentTrackSeg.add(waypt);
|
---|
148 | }
|
---|
149 | }
|
---|
150 | }
|
---|
151 | }
|
---|
152 | }
|
---|
153 | }
|
---|
154 | }
|
---|
155 | }
|
---|
156 | }
|
---|
157 | }
|
---|
158 |
|
---|
159 | /**
|
---|
160 | * @param tcd
|
---|
161 | */
|
---|
162 | private void parseDataFromCourses(TrainingCenterDatabaseT tcd) {
|
---|
163 | if ((tcd.getCourses() != null)
|
---|
164 | && (tcd.getCourses().getCourse() != null)) {
|
---|
165 | for (CourseT course : tcd.getCourses().getCourse()) {
|
---|
166 | if (course.getTrack() != null) {
|
---|
167 | GpxTrack currentTrack = new GpxTrack();
|
---|
168 | gpxData.tracks.add(currentTrack);
|
---|
169 | for (TrackT track : course.getTrack()) {
|
---|
170 | if (track.getTrackpoint() != null) {
|
---|
171 | Collection<WayPoint> currentTrackSeg = new ArrayList<WayPoint>();
|
---|
172 | currentTrack.trackSegs.add(currentTrackSeg);
|
---|
173 | for (TrackpointT tp : track.getTrackpoint()) {
|
---|
174 | WayPoint waypt = convertPoint(tp);
|
---|
175 |
|
---|
176 | if (waypt != null) {
|
---|
177 | currentTrackSeg.add(waypt);
|
---|
178 | }
|
---|
179 | }
|
---|
180 | }
|
---|
181 | }
|
---|
182 | }
|
---|
183 | }
|
---|
184 | }
|
---|
185 | }
|
---|
186 |
|
---|
187 | public GpxData getGpxData() {
|
---|
188 | return gpxData;
|
---|
189 | }
|
---|
190 | }
|
---|