import javax.swing.SwingConstants;
import tim.prune.App;
-import tim.prune.Config;
import tim.prune.ExternalTools;
import tim.prune.GenericFunction;
import tim.prune.I18nManager;
-import tim.prune.data.Altitude;
+import tim.prune.config.Config;
import tim.prune.data.DataPoint;
import tim.prune.data.Distance;
import tim.prune.data.Field;
import tim.prune.data.Timestamp;
import tim.prune.data.Track;
-import tim.prune.data.Distance.Units;
+import tim.prune.gui.profile.SpeedData;
+import tim.prune.gui.profile.VerticalSpeedData;
import tim.prune.load.GenericFileFilter;
/**
*/
public void begin()
{
+ // First check if gnuplot is available
+ if (!ExternalTools.isToolInstalled(ExternalTools.TOOL_GNUPLOT))
+ {
+ _app.showErrorMessage(getNameKey(), "dialog.charts.gnuplotnotfound");
+ return;
+ }
// Make dialog window
if (_dialog == null)
{
// button panel on bottom
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
- // Gnuplot button
- JButton gnuplotButton = new JButton(I18nManager.getText("button.gnuplotpath"));
- gnuplotButton.addActionListener(new ActionListener() {
+ // ok button
+ JButton okButton = new JButton(I18nManager.getText("button.ok"));
+ okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
- setGnuplotPath();
+ showChart(_app.getTrackInfo().getTrack());
+ _dialog.setVisible(false);
}
});
- buttonPanel.add(gnuplotButton);
+ buttonPanel.add(okButton);
// Cancel button
JButton cancelButton = new JButton(I18nManager.getText("button.cancel"));
cancelButton.addActionListener(new ActionListener() {
}
});
buttonPanel.add(cancelButton);
- // ok button
- JButton okButton = new JButton(I18nManager.getText("button.ok"));
- okButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- showChart(_app.getTrackInfo().getTrack());
- _dialog.setVisible(false);
- }
- });
- buttonPanel.add(okButton);
dialogPanel.add(buttonPanel, BorderLayout.SOUTH);
return dialogPanel;
}
private boolean setupDialog(Track inTrack)
{
boolean hasTimes = inTrack.hasData(Field.TIMESTAMP);
- boolean hasAltitudes = inTrack.getAltitudeRange().hasRange();
+ boolean hasAltitudes = inTrack.hasAltitudeData();
_timeRadio.setEnabled(hasTimes);
// Add checks to prevent choosing unavailable combinations
OutputStreamWriter writer = null;
try
{
- Process process = Runtime.getRuntime().exec(Config.getGnuplotPath() + " -persist");
+ final String gnuplotPath = Config.getConfigString(Config.KEY_GNUPLOT_PATH);
+ Process process = Runtime.getRuntime().exec(gnuplotPath + " -persist");
writer = new OutputStreamWriter(process.getOutputStream());
if (showSvg)
{
+ getSvgValue(_svgHeightField, DEFAULT_SVG_HEIGHT) + "\n");
writer.write("set out '" + svgFile.getAbsolutePath() + "'\n");
}
+ else {
+ // For screen output, gnuplot should use the default terminal (windows or x11 or wxt or something)
+ }
if (numCharts > 1) {
writer.write("set multiplot layout " + numCharts + ",1\n");
}
break;
}
// Make a temporary data file for the output (one per subchart)
- File tempFile = File.createTempFile("prunedata", null);
+ File tempFile = File.createTempFile("gpsprunedata", null);
tempFile.deleteOnExit();
// write out values for x and y to temporary file
FileWriter tempFileWriter = null;
try {
tempFileWriter = new FileWriter(tempFile);
- tempFileWriter.write("# Temporary data file for Prune charts\n\n");
+ tempFileWriter.write("# Temporary data file for GpsPrune charts\n\n");
for (int i=0; i<inTrack.getNumPoints(); i++) {
if (xValues.hasData(i) && yValues.hasData(i)) {
tempFileWriter.write("" + xValues.getData(i) + ", " + yValues.getData(i) + "\n");
catch (Exception e) {}
}
+ // Sort out units to use
+ final String distLabel = I18nManager.getText(Config.getUnitSet().getDistanceUnit().getShortnameKey());
+ final String altLabel = I18nManager.getText(Config.getUnitSet().getAltitudeUnit().getShortnameKey());
+ final String speedLabel = I18nManager.getText(Config.getUnitSet().getSpeedUnit().getShortnameKey());
+ final String vertSpeedLabel = I18nManager.getText(Config.getUnitSet().getVerticalSpeedUnit().getShortnameKey());
+
// Set x axis label
if (inDistance) {
- inWriter.write("set xlabel '" + I18nManager.getText("fieldname.distance") + " (" + getUnitsLabel("units.kilometres.short", "units.miles.short") + ")'\n");
+ inWriter.write("set xlabel '" + I18nManager.getText("fieldname.distance") + " (" + distLabel + ")'\n");
}
else {
inWriter.write("set xlabel '" + I18nManager.getText("fieldname.time") + " (" + I18nManager.getText("units.hours") + ")'\n");
switch (inYaxis)
{
case 0: // y axis is distance
- inWriter.write("set ylabel '" + I18nManager.getText("fieldname.distance") + " (" + getUnitsLabel("units.kilometres.short", "units.miles.short") + ")'\n");
+ inWriter.write("set ylabel '" + I18nManager.getText("fieldname.distance") + " (" + distLabel + ")'\n");
chartTitle = I18nManager.getText("fieldname.distance");
break;
case 1: // y axis is altitude
- inWriter.write("set ylabel '" + I18nManager.getText("fieldname.altitude") + " (" + getUnitsLabel("units.metres.short", "units.feet.short") + ")'\n");
+ inWriter.write("set ylabel '" + I18nManager.getText("fieldname.altitude") + " (" + altLabel + ")'\n");
chartTitle = I18nManager.getText("fieldname.altitude");
break;
case 2: // y axis is speed
- inWriter.write("set ylabel '" + I18nManager.getText("fieldname.speed") + " (" + getUnitsLabel("units.kmh", "units.mph") + ")'\n");
+ inWriter.write("set ylabel '" + I18nManager.getText("fieldname.speed") + " (" + speedLabel + ")'\n");
chartTitle = I18nManager.getText("fieldname.speed");
break;
case 3: // y axis is vertical speed
- inWriter.write("set ylabel '" + I18nManager.getText("fieldname.verticalspeed") + " (" + getUnitsLabel("units.metrespersec", "units.feetpersec") + ")'\n");
+ inWriter.write("set ylabel '" + I18nManager.getText("fieldname.verticalspeed") + " (" + vertSpeedLabel + ")'\n");
chartTitle = I18nManager.getText("fieldname.verticalspeed");
break;
}
inWriter.write("plot '" + tempFile.getAbsolutePath() + "' title '" + chartTitle + "' with filledcurve y1=0 lt rgb \"#009000\"\n");
}
- /**
- * Get the units label for the given keys
- * @param inMetric key if metric
- * @param inImperial key if imperial
- * @return display label with appropriate text
- */
- private static String getUnitsLabel(String inMetric, String inImperial)
- {
- String key = Config.getUseMetricUnits()?inMetric:inImperial;
- return I18nManager.getText(key);
- }
-
/**
* Calculate the distance values for each point in the given track
{
totalRads += DataPoint.calculateRadiansBetween(prevPoint, currPoint);
}
- if (Config.getUseMetricUnits()) {
- values.setData(i, Distance.convertRadiansToDistance(totalRads, Units.KILOMETRES));
- } else {
- values.setData(i, Distance.convertRadiansToDistance(totalRads, Units.MILES));
- }
+
+ // distance values use currently configured units
+ values.setData(i, Distance.convertRadiansToDistance(totalRads));
+
prevPoint = currPoint;
}
return values;
if (currPoint.hasTimestamp())
{
if (!currPoint.getSegmentStart() && prevTimestamp != null) {
- seconds += (currPoint.getTimestamp().getSecondsSince(prevTimestamp));
+ seconds += (currPoint.getTimestamp().getMillisecondsSince(prevTimestamp) / 1000.0);
}
values.setData(i, seconds / 60.0 / 60.0);
prevTimestamp = currPoint.getTimestamp();
private static ChartSeries getAltitudeValues(Track inTrack)
{
ChartSeries values = new ChartSeries(inTrack.getNumPoints());
- Altitude.Format altFormat = Config.getUseMetricUnits()?Altitude.Format.METRES:Altitude.Format.FEET;
+ final double multFactor = Config.getUnitSet().getAltitudeUnit().getMultFactorFromStd();
for (int i=0; i<inTrack.getNumPoints(); i++) {
if (inTrack.getPoint(i).hasAltitude()) {
- values.setData(i, inTrack.getPoint(i).getAltitude().getValue(altFormat));
+ values.setData(i, inTrack.getPoint(i).getAltitude().getMetricValue() * multFactor);
}
}
return values;
*/
private static ChartSeries getSpeedValues(Track inTrack)
{
- // Calculate speeds and fill in in values array
- ChartSeries values = new ChartSeries(inTrack.getNumPoints());
- DataPoint prevPoint = null, currPoint = null, nextPoint = null;
- DataPoint[] points = getDataPoints(inTrack, false);
+ // Calculate speeds using the same formula as the profile chart
+ SpeedData speeds = new SpeedData(inTrack);
+ speeds.init(Config.getUnitSet());
+
+ final int numPoints = inTrack.getNumPoints();
+ ChartSeries values = new ChartSeries(numPoints);
// Loop over collected points
- for (int i=1; i<(points.length-1); i++)
+ for (int i=0; i<numPoints; i++)
{
- prevPoint = points[i-1];
- currPoint = points[i];
- nextPoint = points[i+1];
- if (prevPoint != null && currPoint != null && nextPoint != null
- && nextPoint.getTimestamp().isAfter(currPoint.getTimestamp())
- && currPoint.getTimestamp().isAfter(prevPoint.getTimestamp()))
+ if (speeds.hasData(i))
{
- // Calculate average speed between prevPoint and nextPoint
- double rads = DataPoint.calculateRadiansBetween(prevPoint, currPoint)
- + DataPoint.calculateRadiansBetween(currPoint, nextPoint);
- double time = nextPoint.getTimestamp().getSecondsSince(prevPoint.getTimestamp()) / 60.0 / 60.0;
- // Convert to distance and pass to chartseries
- if (Config.getUseMetricUnits()) {
- values.setData(i, Distance.convertRadiansToDistance(rads, Units.KILOMETRES) / time);
- } else {
- values.setData(i, Distance.convertRadiansToDistance(rads, Units.MILES) / time);
- }
+ values.setData(i, speeds.getData(i));
}
}
return values;
*/
private static ChartSeries getVertSpeedValues(Track inTrack)
{
- // Calculate speeds and fill in in values array
- ChartSeries values = new ChartSeries(inTrack.getNumPoints());
- Altitude.Format altFormat = Config.getUseMetricUnits()?Altitude.Format.METRES:Altitude.Format.FEET;
- DataPoint prevPoint = null, currPoint = null, nextPoint = null;
- DataPoint[] points = getDataPoints(inTrack, true); // require that points have altitudes too
+ // Calculate speeds using the same formula as the profile chart
+ VerticalSpeedData speeds = new VerticalSpeedData(inTrack);
+ speeds.init(Config.getUnitSet());
+
+ final int numPoints = inTrack.getNumPoints();
+ ChartSeries values = new ChartSeries(numPoints);
// Loop over collected points
- for (int i=1; i<(points.length-1); i++)
+ for (int i=0; i<numPoints; i++)
{
- prevPoint = points[i-1];
- currPoint = points[i];
- nextPoint = points[i+1];
- if (prevPoint != null && currPoint != null && nextPoint != null
- && nextPoint.getTimestamp().isAfter(currPoint.getTimestamp())
- && currPoint.getTimestamp().isAfter(prevPoint.getTimestamp()))
+ if (speeds.hasData(i))
{
- // Calculate average vertical speed between prevPoint and nextPoint
- double vspeed = (nextPoint.getAltitude().getValue(altFormat) - prevPoint.getAltitude().getValue(altFormat))
- * 1.0 / nextPoint.getTimestamp().getSecondsSince(prevPoint.getTimestamp());
- values.setData(i, vspeed);
+ values.setData(i, speeds.getData(i));
}
}
return values;
}
- /**
- * Get an array of DataPoints with data for the charts
- * @param inTrack track object containing points
- * @param inRequireAltitudes true if only points with altitudes are considered
- * @return array of points with contiguous non-null elements (<= size) with timestamps
- */
- private static DataPoint[] getDataPoints(Track inTrack, boolean inRequireAltitudes)
- {
- DataPoint[] points = new DataPoint[inTrack.getNumPoints()];
- DataPoint currPoint = null;
- int pointNum = 0;
- // Loop over all points
- for (int i=0; i<inTrack.getNumPoints(); i++)
- {
- currPoint = inTrack.getPoint(i);
- if (currPoint != null && !currPoint.isWaypoint() && currPoint.hasTimestamp()
- && (!inRequireAltitudes || currPoint.hasAltitude()))
- {
- points[pointNum] = currPoint;
- pointNum++;
- }
- }
- // Any elements at the end of the array will stay null
- // Also note, chronological order is not checked
- return points;
- }
-
-
/**
* Select a file to write for the SVG output
- * @return
+ * @return selected File object or null if cancelled
*/
private File selectSvgFile()
{
_fileChooser.setFileFilter(new GenericFileFilter("filetype.svg", new String[] {"svg"}));
_fileChooser.setAcceptAllFileFilterUsed(false);
// start from directory in config which should be set
- File configDir = Config.getWorkingDirectory();
- if (configDir != null) {_fileChooser.setCurrentDirectory(configDir);}
+ String configDir = Config.getConfigString(Config.KEY_TRACK_DIR);
+ if (configDir != null) {_fileChooser.setCurrentDirectory(new File(configDir));}
}
boolean chooseAgain = true;
while (chooseAgain)
{
return file;
}
- else {
- chooseAgain = true;
- }
+ chooseAgain = true;
}
}
// Cancel pressed so no file selected
if (inNumCharts == 3) {return new int[] {40, 60, 20, 20, 0, 20};}
return new int[] {54, 46, 36, 18, 18, 18, 0, 18};
}
-
- /**
- * Prompt the user to set/edit the path to gnuplot
- */
- private void setGnuplotPath()
- {
- String currPath = Config.getGnuplotPath();
- Object path = JOptionPane.showInputDialog(_dialog,
- I18nManager.getText("dialog.charts.gnuplotpath"),
- I18nManager.getText(getNameKey()),
- JOptionPane.QUESTION_MESSAGE, null, null, "" + currPath);
- if (path != null)
- {
- String pathString = path.toString().trim();
- if (!pathString.equals("") && !pathString.equals(currPath)) {
- Config.setGnuplotPath(pathString);
- // warn if gnuplot still not found
- if (!ExternalTools.isGnuplotInstalled()) {
- _app.showErrorMessage(getNameKey(), "dialog.charts.gnuplotnotfound");
- }
- }
- }
- }
}