now supporting all gpx files with both tracks and routes.
[utils] / gps / src / main / java / org / wamblee / gpx / TrackStatistics.java
1 package org.wamblee.gpx;
2
3 import java.io.FileOutputStream;
4 import java.io.IOException;
5 import java.io.OutputStream;
6 import java.io.Serializable;
7 import java.util.ArrayList;
8 import java.util.List;
9
10 import org.jfree.chart.ChartFactory;
11 import org.jfree.chart.ChartUtilities;
12 import org.jfree.chart.JFreeChart;
13 import org.jfree.chart.plot.PlotOrientation;
14 import org.jfree.data.xy.XYSeries;
15 import org.jfree.data.xy.XYSeriesCollection;
16 import org.wamblee.general.Pair;
17 import org.wamblee.gps.geometry.Point;
18 import org.wamblee.gps.geometry.ReferenceCoordinateSystem;
19 import org.wamblee.gps.track.Track;
20
21 public class TrackStatistics implements Serializable {
22     
23     private Track _track; 
24     
25     public TrackStatistics(Track aTrack) {
26         _track = aTrack; 
27     }
28     
29     public void writeHeightProfileJpg(OutputStream aStream, int aWidth, int aHeight) throws IOException {
30         List<Pair<Double,Double>> data = computeElevationProfile();
31         XYSeriesCollection dataset = createDataset(data, "height");
32         JFreeChart chart = ChartFactory.createXYLineChart(
33                 "Height Profile", 
34                 "Distance(km)",
35                 "Height(m)",
36                 dataset,
37                 PlotOrientation.VERTICAL,
38                 true,
39                 true,
40                 false);
41         ChartUtilities.writeChartAsJPEG(aStream, chart, aWidth, aHeight);
42     }
43     
44     private static XYSeriesCollection createDataset(List<Pair<Double, Double>> aHeightProfile, String aName) {
45         XYSeries series = new XYSeries(aName, false);
46         for (Pair<Double,Double> point: aHeightProfile) { 
47             series.add(point.getFirst()/1000.0, point.getSecond());
48         }
49         XYSeriesCollection dataset = new XYSeriesCollection(series);
50         return dataset;
51     }
52     
53     public List<Pair<Double, Double>> computeElevationProfile() {
54         List<Pair<Double,Double>> results = new ArrayList<Pair<Double,Double>>();
55         double distance = 0.0; 
56         for (int i = 0; i < _track.size(); i++) { 
57             Point point = _track.getPoint(i);
58             results.add(new Pair<Double,Double>(distance, point.getCoordinates().getX3()));
59             if ( i+1 < _track.size()) { 
60                 Point nextPoint = _track.getPoint(i+1); 
61                 distance += ReferenceCoordinateSystem.distance(point, nextPoint);
62             }
63         }
64         return results; 
65     }
66     
67     public double getTotalClimb() {
68         
69         List<Pair<Double,Double>> data = computeElevationProfile(); 
70         double result = 0.0;
71         
72         double lastHeight = data.get(0).getSecond();
73         for ( int i = 1; i < data.size(); i++) { 
74             double height = data.get(i).getSecond();
75             if ( height > lastHeight) { 
76                 result += (height-lastHeight); 
77             }
78             lastHeight = height; 
79         }
80         return result; 
81     }
82     
83     public double getDistance() { 
84         List<Pair<Double,Double>> data = computeElevationProfile(); 
85         return data.get(data.size()-1).getFirst();
86     }
87 }