package org.wamblee.gpx; import java.awt.Color; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.Serializable; 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.TrackSegment; public class TrackStatistics implements Serializable { private TrackSegment _track; public TrackStatistics(TrackSegment aTrack) { _track = aTrack; } public void writeHeightProfilePng(OutputStream aStream, int aWidth, int aHeight) throws IOException { List> data = computeElevationProfile(); XYSeriesCollection dataset = createDataset(data, "height"); JFreeChart chart = ChartFactory.createXYLineChart("Height Profile", "Distance(km)", "Height(m)", dataset, PlotOrientation.VERTICAL, true, true, false); chart.setBackgroundPaint(Color.WHITE); ChartUtilities.writeChartAsPNG(aStream, chart, aWidth, aHeight); } private static XYSeriesCollection createDataset( List> aHeightProfile, String aName) { XYSeries series = new XYSeries(aName, false); for (Pair point : aHeightProfile) { series.add(point.getFirst() / 1000.0, point.getSecond()); } XYSeriesCollection dataset = new XYSeriesCollection(series); return dataset; } public List> computeElevationProfile() { List> results = new ArrayList>(); double distance = 0.0; for (int i = 0; i < _track.size(); i++) { Point point = _track.getPoint(i); results.add(new Pair(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> data = computeElevationProfile(); double result = 0.0; if ( data.size() == 0 ) { return result; } 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> data = computeElevationProfile(); if (data.size() == 0) { return 0.0; } return data.get(data.size() - 1).getFirst(); } }