package com.awsmithson.tcx2nikeplus.convert; import com.awsmithson.tcx2nikeplus.util.Log; import com.awsmithson.tcx2nikeplus.util.Util; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import java.io.File; import javax.annotation.Nonnull; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; /** * Converts a garmin gpx file to one that can be uploaded to nike+. * @author angus */ @Deprecated public class ConvertGpx { private static final @Nonnull Log log = Log.getInstance(); public Document generateNikePlusGpx(File tcxFile) throws ConverterException { try { Document tcxDoc = Util.generateDocument(tcxFile); return generateNikePlusGpx(tcxDoc); } catch (Throwable throwable) { throw new ConverterException(throwable.getMessage(), throwable); } } public Document generateNikePlusGpx(Document inDoc) throws ConverterException { try { // Create output document DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document outDoc = db.newDocument(); // gpx (root) Element gpxElement = Util.appendElement(outDoc, "gpx", null, "xmlns", "http://www.topografix.com/GPX/1/1", "creator", "NikePlus", "version", "1.1"); // trk Element trk = Util.appendElement(gpxElement, "trk"); Util.appendCDATASection(trk, "name", "4c888a06"); Util.appendCDATASection(trk, "desc", "workout"); // trkseg Element trkSeg = Util.appendElement(trk, "trkseg"); // trkpt's appendTrkptElements(inDoc, trkSeg); return outDoc; } catch (Throwable throwable) { throw new ConverterException(throwable.getMessage(), throwable); } } /** * Appends all the <trkrpt> data to the output xml. * <p> * I have chosen to iterate through the garmin data and append rather than copy it all over then iterate * through it and remove unrequired data. The reason for this is that if garmin decided to modify the gpx * schema I do not have to worry about modifying my code to remove additional elements. * At the time of writing (2010-09-13) nike+ use gpx data as follows: * <pre> * {@code * <trkpt lat="51.7944969579" lon="-0.0769600122"> * <ele>50.5970001221</ele> * <time>2010-09-09T07:18:04Z</time> * </trkpt> * } * </pre> * @param inDoc The garmin gpx document we are reading the data from. * @param trkSeg The xml element in the output document to which we are appending the data. */ private void appendTrkptElements(Document inDoc, Element trkSeg) { NodeList trkpts = inDoc.getElementsByTagName("trkpt"); int trkptsLength = trkpts.getLength(); for (int i = 0; i < trkptsLength; ++i) { Node trkptGarmin = trkpts.item(i); NamedNodeMap latlon = trkptGarmin.getAttributes(); String lon = Util.getSimpleNodeValue(latlon.getNamedItem("lon")); String lat = Util.getSimpleNodeValue(latlon.getNamedItem("lat")); Element trkptNike = Util.appendElement(trkSeg, "trkpt", null, "lat", lat, "lon", lon); for (Node n = trkptGarmin.getFirstChild(); n != null; n = n.getNextSibling()) { String nodeName = n.getNodeName(); if ((nodeName.equals("ele")) || (nodeName.equals("time"))) Util.appendElement(trkptNike, nodeName, Util.getSimpleNodeValue(n)); } } } public static void main(String[] args) { File inFile = new File(args[0]); ConvertGpx c = new ConvertGpx(); try { Document doc = c.generateNikePlusGpx(inFile); Util.writeDocument(doc, "gpxXML.xml"); } catch (Throwable t) { log.out(t); } } }