--- /dev/null
+package org.wamblee.gpx;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jfree.chart.ChartFactory;
+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.geometry.Point;
+import org.wamblee.gps.geometry.ReferenceCoordinateSystem;
+import org.wamblee.gps.track.Track;
+
+public class TrackStatistics {
+
+ private Track _track;
+
+ public TrackStatistics(Track aTrack) {
+ _track = aTrack;
+ }
+
+ public void writeHeightProfileJpg(OutputStream aStream, int aWidth, int aHeight) throws IOException {
+ List<Pair<Double,Double>> data = computeElevationProfile();
+ XYSeriesCollection dataset = createDataset(data, "height");
+ JFreeChart chart = ChartFactory.createXYLineChart(
+ "Height Profile",
+ "Distance(m)",
+ "Height(m)",
+ dataset,
+ PlotOrientation.VERTICAL,
+ true,
+ true,
+ false);
+ ChartUtilities.writeChartAsJPEG(aStream, chart, aWidth, aHeight);
+ }
+
+ private static XYSeriesCollection createDataset(List<Pair<Double, Double>> aHeightProfile, String aName) {
+ XYSeries series = new XYSeries(aName, false);
+ for (Pair<Double,Double> point: aHeightProfile) {
+ series.add(point.getFirst()/1000.0, point.getSecond());
+ }
+ XYSeriesCollection dataset = new XYSeriesCollection(series);
+ return dataset;
+ }
+
+ public List<Pair<Double, Double>> computeElevationProfile() {
+ List<Pair<Double,Double>> results = new ArrayList<Pair<Double,Double>>();
+ double distance = 0.0;
+ for (int i = 0; i < _track.size(); i++) {
+ Point point = _track.getPoint(i);
+ results.add(new Pair<Double,Double>(distance, point.getCoordinates().getX3()));
+ if ( i+1 < _track.size()) {
+ Point nextPoint = _track.getPoint(i+1);
+ distance += ReferenceCoordinateSystem.distance(point, nextPoint);
+ }
+ }
+ return results;
+ }
+
+ public double getTotalClimb() {
+
+ List<Pair<Double,Double>> data = computeElevationProfile();
+ double result = 0.0;
+
+ double lastHeight = data.get(0).getSecond();
+ for ( int i = 1; i < data.size(); i++) {
+ double height = data.get(i).getSecond();
+ if ( height > lastHeight) {
+ result += (height-lastHeight);
+ }
+ lastHeight = height;
+ }
+ return result;
+ }
+
+ public double getDistance() {
+ List<Pair<Double,Double>> data = computeElevationProfile();
+ return data.get(data.size()-1).getFirst();
+ }
+}