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