/*
* Copyright 2012-2014 Coronastreet Networks
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License
*/
package org.coronastreet.gpxconverter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JTextArea;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
@SuppressWarnings("deprecation")
public class Converter implements Runnable {
private Document inDoc;
private Document outDoc;
private String inFile;
private String outFile;
List<Trkpt> trackPoints;
private String rideStartTime;
private JTextArea statusTextArea;
protected String newline = "\n";
private String authToken;
private String activityType;
private String activityName;
private String deviceType;
private String Brand;
private String totalTimeInSeconds;
private String distanceMeters;
private boolean hasAltimeter = false;
private boolean runStrava = false;
private boolean runRWGPS = false;
private boolean runGarmin = false;
public Converter(){
//create a list to hold the employee objects
trackPoints = new ArrayList<Trkpt>();
// Define the temp file so we know where it is on diff systems.
if (GPXConverter.isWindows()) {
outFile = "C:\\Temp\\temp.tcx";
} else if (GPXConverter.isUnix()) {
outFile = "/tmp/temp.tcx";
} else {
// Who knows where this will show up...
outFile = "temp.tcx";
}
}
@Override
public void run() {
this.convert();
}
public void convert () {
//parse the GPX file and get the dom object
loadInFile(inFile);
//load the Tracks from the GPX File
parseInFile();
if (runRWGPS) {
doRWGPS();
}
if (runStrava) {
doStrava();
}
if (runGarmin) {
doGarmin();
}
}
// Not Currently used....but will use maybe someday...
@SuppressWarnings("unused")
private void printOutFile(){
try {
OutputFormat format = new OutputFormat(outDoc);
format.setIndenting(true);
XMLSerializer serializer = new XMLSerializer(new FileOutputStream(new File(outFile)), format);
log("Writing out TCX file.");
serializer.serialize(outDoc);
} catch(IOException ie) {
ie.printStackTrace();
}
}
private void doRWGPS() {
RideWithGPS rwgps = new RideWithGPS();
rwgps.setEmail(GPXConverter.getPref("rwgps_username"));
try {
rwgps.setPassword(AccountManager.decrypt(GPXConverter.getPref("rwgps_password")));
} catch (Exception e) {
e.printStackTrace();
}
rwgps.setTripName(activityName);
rwgps.setDescription(activityName);
rwgps.setActivityType(activityType);
rwgps.setStatusTextArea(statusTextArea);
rwgps.setTrackPoints(trackPoints);
if (rwgps.processData()) {
rwgps.upload();
}
}
private void doStrava() {
StravaForm strava = new StravaForm();
strava.setEmail(GPXConverter.getPref("strava_username"));
try {
strava.setPassword(AccountManager.decrypt(GPXConverter.getPref("strava_password")));
} catch (Exception e) {
e.printStackTrace();
}
strava.setTripName(activityName);
strava.setActivityType(activityType);
strava.setHasAltimeter(hasAltimeter);
strava.setStatusTextArea(statusTextArea);
strava.setTrackPoints(trackPoints);
strava.setRideStartTime(rideStartTime);
if (strava.processData()) {
strava.upload();
}
}
private void doGarmin() {
GarminForm garmin = new GarminForm();
garmin.setEmail(GPXConverter.getPref("garmin_username"));
try {
garmin.setPassword(AccountManager.decrypt(GPXConverter.getPref("garmin_password")));
} catch (Exception e) {
e.printStackTrace();
}
garmin.setTripName(activityName);
garmin.setActivityType(activityType);
garmin.setHasAltimeter(hasAltimeter);
garmin.setStatusTextArea(statusTextArea);
garmin.setTrackPoints(trackPoints);
garmin.setRideStartTime(rideStartTime);
// Garmin doesn't seem to calculate these on it's own....
garmin.setTotalTimeInSeconds(totalTimeInSeconds);
garmin.setDistanceMeters(distanceMeters);
if (garmin.processData()) {
garmin.upload();
}
}
private String getTextValue(Element ele, String tagName) {
String textVal = null;
NodeList nl;
nl = ele.getElementsByTagName(tagName);
if(nl != null && nl.getLength() > 0) {
Element el = (Element)nl.item(0);
textVal = el.getFirstChild().getNodeValue();
}
return textVal;
}
private String getTextValue(Element ele, String[] tagNames) {
String textVal = null;
NodeList nl;
for (String tagName: tagNames) {
nl = ele.getElementsByTagName(tagName);
if(nl != null && nl.getLength() > 0) {
Element el = (Element)nl.item(0);
textVal = el.getFirstChild().getNodeValue();
}
}
return textVal;
}
private void parseInFile(){
log("Parsing Input File...");
//get the root element
Element docEle = (Element) inDoc.getDocumentElement();
int totalDistance = 0; //Distance in Meters
long totalTime = 0; // Total time in milliseconds
//get a node list of elements
NodeList nl = docEle.getElementsByTagName("trkpt");
Location lastLoc = null;
if(nl != null && nl.getLength() > 0) {
for(int i = 0 ; i < nl.getLength();i++) {
//get the Trackpoint element
Element el = (Element)nl.item(i);
Trkpt tp = new Trkpt();
//get the Trackpoint object
tp.setTime(getTextValue(el, "time"));
tp.setLon(el.getAttribute("lon"));
tp.setLat(el.getAttribute("lat"));
tp.setElevation(getTextValue(el, "ele"));
// These fields can have multiple names (Garmin vs. Mio, etc.)
tp.setHr(getTextValue(el, new String[]{"gpxtpx:hr", "heartrate"}));
tp.setCad(getTextValue(el, new String[]{"gpxtpx:cad", "cadence"}));
tp.setTemp(getTextValue(el, new String[]{"gpxtpx:atemp", "temp"}));
//tp.dump();
//add it to list
trackPoints.add(tp);
// Do some calculations for distance.
if (lastLoc == null) {
lastLoc = new Location(tp);
} else {
Location newLoc = new Location(tp);
totalDistance += lastLoc.distanceTo(newLoc);
totalTime += (newLoc.getTime() - lastLoc.getTime());
lastLoc = newLoc;
}
}
}
log("Imported " + trackPoints.size() + " trackpoints.");
log("Total Ride Time: " + getNiceTime(totalTime));
totalTimeInSeconds = Long.toString(totalTime / 1000);
double miles = totalDistance * 0.00062137119;
log("Total Distance Covered: " + miles + " miles.");
distanceMeters = Long.toString(totalDistance);
// set StartTime
NodeList ml = docEle.getElementsByTagName("metadata");
if (ml == null || ml.getLength() == 0) {
rideStartTime = trackPoints.get(0).getTime();
} else {
rideStartTime = getTextValue((Element)ml.item(0), "time");
}
log("Importing start time as " + rideStartTime);
}
public static String getNiceTime(long millis) {
int hours = (int) millis / (1000*60*60);
int minutes = (int) (millis % (1000*60*60)) / (1000*60);
int seconds = (int) (millis % (1000*60*60)) % (1000*60) / 1000;
StringBuilder sb = new StringBuilder(64);
sb.append(hours);
sb.append(" Hours, ");
sb.append(minutes);
sb.append(" Minutes, ");
sb.append(seconds);
sb.append(" Seconds.");
return(sb.toString());
}
private void log(String s) {
this.statusTextArea.append(s + "\n");
this.statusTextArea.repaint(1);
}
private void loadInFile(String file){
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db = dbf.newDocumentBuilder();
inDoc = db.parse(file);
}catch(ParserConfigurationException pce) {
log(pce.getMessage());
}catch(SAXException se) {
log(se.getMessage());
}catch(IOException ioe) {
log(ioe.getMessage());
}
}
public String getInFile() {
return inFile;
}
public void setInFile(String inFile) {
this.inFile = inFile;
}
public String getOutFile() {
return outFile;
}
public void setOutFile(String outFile) {
this.outFile = outFile;
}
public String getAuthToken() {
return authToken;
}
public void setAuthToken(String authToken) {
this.authToken = authToken;
}
public String getActivityType() {
return activityType;
}
public void setActivityType(String at) {
activityType = at;
}
public String getActivityName() {
return activityName;
}
public void setActivityName(String an) {
activityName = an;
}
public String getDeviceType() {
return deviceType;
}
public void setDeviceType(String dt) {
deviceType = dt;
}
public String getBrand() {
return Brand;
}
public void setBrand(String brand) {
Brand = brand;
}
public void setStatusTextArea(JTextArea txtArea) {
this.statusTextArea = txtArea;
}
public boolean hasAltimeter() {
return hasAltimeter;
}
public void setHasAltimeter(boolean hasAltimeter) {
this.hasAltimeter = hasAltimeter;
}
public void setDoStrava(boolean b) {
this.runStrava = b;
}
public void setDoRWGPS(boolean b) {
this.runRWGPS = b;
}
public void setDoGarmin(boolean b) {
this.runGarmin = b;
}
}