/* * Copyright 2006 the original author or authors. * * 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.wamblee.gpx; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.xml.parsers.ParserConfigurationException; import org.dom4j.Document; import org.dom4j.Element; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartFrame; import org.jfree.chart.ChartUtilities; import org.jfree.chart.JFreeChart; import org.jfree.chart.plot.PlotOrientation; import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; import org.wamblee.general.Pair; import org.wamblee.gps.coordinates.Point; import org.wamblee.gps.coordinates.ReferenceCoordinateSystem; import org.wamblee.gps.track.Track; import org.wamblee.gps.track.TrackPoint; import org.wamblee.xml.DomUtils; import org.xml.sax.SAXException; /** * Parses a GPX file and prints out a data file with each trackpoints distance from the start of the * track and its elevation, separated by a space. */ public class GpxPlotter { public static void main(String[] aArgs) throws ParserConfigurationException, FileNotFoundException, SAXException, IOException { File file = new File(aArgs[0]); Document doc = DomUtils.convert(DomUtils.read(new FileInputStream(file))); Track track = parseTrack(doc); List> elevationProfile = computeElevationProfile(track); printTrack(elevationProfile); computeTotalClimb(elevationProfile); plotElevationProfile(elevationProfile); } /** * @param doc */ private static Track parseTrack(Document doc) { Track track = new Track(); Element root = doc.getRootElement().element("trk").element("trkseg"); for ( Iterator i =root.elementIterator("trkpt"); i.hasNext(); ) { Element trkpt = (Element)i.next(); track.addPoint(parseTrackPoint(trkpt)); } return track; } /** * @param trkpt */ private static TrackPoint parseTrackPoint(Element trkpt) { //System.out.println(trkpt.asXML() + "|\n"); double latitude = new Double(trkpt.attributeValue("lat")); double longitude = new Double(trkpt.attributeValue("lon")); double elevation = new Double(trkpt.elementText("ele")); //System.out.println(" lat = " + lat + " lon = " + lon + " ele = " + ele); return new TrackPoint(latitude, longitude, elevation); } private static List> computeElevationProfile(Track aTrack) { List> results = new ArrayList>(); double distance = 0.0; for (int i = 0; i < aTrack.size(); i++) { Point point = aTrack.getPoint(i); results.add(new Pair(distance, point.getCoordinates().getX3())); if ( i+1 < aTrack.size()) { Point nextPoint = aTrack.getPoint(i+1); distance += ReferenceCoordinateSystem.distance(point, nextPoint); } } return results; } private static void printTrack(List> aHeightProfile) { for (Pair point: aHeightProfile) { System.out.println(point.getFirst() + " " + point.getSecond()); } } private static void computeTotalClimb(List> aHeightProfile) { double result = 0.0; double lastHeight = aHeightProfile.get(0).getSecond(); for ( int i = 1; i < aHeightProfile.size(); i++) { double height = aHeightProfile.get(i).getSecond(); if ( height > lastHeight) { result += (height-lastHeight); } lastHeight = height; } System.out.println("Total climb: " + result); } private static void plotElevationProfile(List> aHeightProfile) throws IOException { XYSeries series = new XYSeries("height"); for (Pair point: aHeightProfile) { series.add(point.getFirst(), point.getSecond()); } XYSeriesCollection dataset = new XYSeriesCollection(series); JFreeChart chart = ChartFactory.createXYLineChart( "Height Profile", "Distance(m)", "Height(m)", dataset, PlotOrientation.VERTICAL, true, true, false); ChartUtilities.writeChartAsPNG(new FileOutputStream("test.png"), chart, 600, 300); ChartFrame frame = new ChartFrame("test", chart); frame.pack(); frame.setVisible(true); } }