Skip to content
Commits on Source (4)
# Build script
# Version number
PRUNENAME=gpsprune_19
PRUNENAME=gpsprune_19.1
# remove compile directory
rm -rf compile
# remove dist directory
......
gpsprune (19-3) UNRELEASED; urgency=medium
gpsprune (19.1-1) unstable; urgency=medium
* New upstream release.
* Bump Standards-Version to 4.2.0, no changes.
-- Bas Couwenberg <sebastic@debian.org> Sat, 04 Aug 2018 12:09:37 +0200
-- Bas Couwenberg <sebastic@debian.org> Sun, 26 Aug 2018 10:38:28 +0200
gpsprune (19-2) unstable; urgency=medium
......
......@@ -36,9 +36,9 @@ import tim.prune.gui.profile.ProfileChart;
public class GpsPrune
{
/** Version number of application, used in about screen and for version check */
public static final String VERSION_NUMBER = "19";
public static final String VERSION_NUMBER = "19.1";
/** Build number, just used for about screen */
public static final String BUILD_NUMBER = "362";
public static final String BUILD_NUMBER = "363c";
/** Static reference to App object */
private static App APP = null;
......
......@@ -14,7 +14,10 @@ public abstract class GradientCalculator
*/
public static void calculateGradient(Track inTrack, int inIndex, SpeedValue inValue)
{
inValue.setInvalid();
if (inValue != null)
{
inValue.setInvalid();
}
if (inTrack == null || inIndex < 0 || inValue == null)
{
System.err.println("Cannot calculate gradient for index " + inIndex);
......
......@@ -16,7 +16,10 @@ public abstract class SpeedCalculator
*/
public static void calculateSpeed(Track inTrack, int inIndex, SpeedValue inValue)
{
inValue.setInvalid();
if (inValue != null)
{
inValue.setInvalid();
}
if (inTrack == null || inIndex < 0 || inValue == null)
{
System.err.println("Cannot calculate speed for index " + inIndex);
......
......@@ -366,7 +366,7 @@ public class TimestampUtc extends Timestamp
{
return _text;
}
// Nothing cached, so use the regular one
return super.getText(inFormat, inTimezone);
}
......
......@@ -120,7 +120,7 @@ public class AddTimeOffset extends GenericFunction
/** Key typed */
public void keyTyped(KeyEvent event) {
final boolean isNumber = "1234567890".indexOf(event.getKeyChar()) >= 0;
_okButton.setEnabled(isNumber || getOffsetSecs() != 0L);
_okButton.setEnabled(isNumber || getOffsetSecs() != 0L);
}
};
MouseAdapter mouseListener = new MouseAdapter() {
......
......@@ -191,35 +191,33 @@ public class GetWikipediaFunction extends GenericDownloaderFunction
{
InputStream in = GetWikipediaFunction.class.getResourceAsStream("/tim/prune/function/search/wikimedia_galleries.txt");
reader = new BufferedReader(new InputStreamReader(in));
if (reader != null)
ArrayList<SearchResult> trackList = new ArrayList<SearchResult>();
DataPoint herePoint = new DataPoint(new Latitude(inLat, Latitude.FORMAT_DEG), new Longitude(inLon, Longitude.FORMAT_DEG), null);
// Loop through the file line by line, looking for nearby points
String line = null;
while ((line = reader.readLine()) != null)
{
ArrayList<SearchResult> trackList = new ArrayList<SearchResult>();
DataPoint herePoint = new DataPoint(new Latitude(inLat, Latitude.FORMAT_DEG), new Longitude(inLon, Longitude.FORMAT_DEG), null);
// Loop through the file line by line, looking for nearby points
String line = null;
while ((line = reader.readLine()) != null)
String[] lineComps = line.split("\t");
if (lineComps.length == 4)
{
String[] lineComps = line.split("\t");
if (lineComps.length == 4)
DataPoint p = new DataPoint(new Latitude(lineComps[2]), new Longitude(lineComps[3]), null);
double distFromHere = Distance.convertRadiansToDistance(
DataPoint.calculateRadiansBetween(p, herePoint), UnitSetLibrary.UNITS_KILOMETRES);
if (distFromHere < MAX_DISTANCE)
{
DataPoint p = new DataPoint(new Latitude(lineComps[2]), new Longitude(lineComps[3]), null);
double distFromHere = Distance.convertRadiansToDistance(
DataPoint.calculateRadiansBetween(p, herePoint), UnitSetLibrary.UNITS_KILOMETRES);
if (distFromHere < MAX_DISTANCE)
{
SearchResult gallery = new SearchResult();
gallery.setTrackName(I18nManager.getText("dialog.wikipedia.gallery") + ": " + lineComps[0]);
gallery.setDescription(lineComps[1]);
gallery.setLatitude(lineComps[2]);
gallery.setLongitude(lineComps[3]);
gallery.setWebUrl("https://commons.wikimedia.org/wiki/" + lineComps[0]);
gallery.setLength(distFromHere * 1000.0); // convert from km to m
trackList.add(gallery);
}
SearchResult gallery = new SearchResult();
gallery.setTrackName(I18nManager.getText("dialog.wikipedia.gallery") + ": " + lineComps[0]);
gallery.setDescription(lineComps[1]);
gallery.setLatitude(lineComps[2]);
gallery.setLongitude(lineComps[3]);
gallery.setWebUrl("https://commons.wikimedia.org/wiki/" + lineComps[0]);
gallery.setLength(distFromHere * 1000.0); // convert from km to m
trackList.add(gallery);
}
}
_trackListModel.addTracks(trackList, true);
}
_trackListModel.addTracks(trackList, true);
}
catch (java.io.IOException e) {
System.err.println("Exception trying to read wikimedia file : " + e.getMessage());
......
......@@ -469,7 +469,7 @@ public class SelectTimezoneFunction extends GenericFunction
}
}
// If the region and offset were given, then list is unlimited
nameList.setUnlimited(inRegion != null && inOffset != null && inRegion != null);
nameList.setUnlimited(inRegion != null && inOffset != null);
// Add all the found names to the listbox
for (String name : zoneNames)
{
......
......@@ -24,13 +24,15 @@ public abstract class UrlGenerator
public enum WebService
{
MAP_SOURCE_GOOGLE, /* Google maps */
MAP_SOURCE_OSM, /* OpenStreetMap */
MAP_SOURCE_MAPQUEST, /* Mapquest */
MAP_SOURCE_YAHOO, /* Yahoo */
MAP_SOURCE_BING, /* Bing */
MAP_SOURCE_PEAKFINDER, /* PeakFinder */
MAP_SOURCE_GEOHACK, /* Geohack */
MAP_SOURCE_GOOGLE, /* Google maps */
MAP_SOURCE_OSM, /* OpenStreetMap */
MAP_SOURCE_MAPQUEST, /* Mapquest */
MAP_SOURCE_YAHOO, /* Yahoo */
MAP_SOURCE_BING, /* Bing */
MAP_SOURCE_PEAKFINDER, /* PeakFinder */
MAP_SOURCE_GEOHACK, /* Geohack */
MAP_SOURCE_INLINESKATE, /* Inlinemap.net */
MAP_SOURCE_GRAPHHOPPER /* Routing with GraphHopper */
}
/**
......@@ -53,7 +55,10 @@ public abstract class UrlGenerator
return generateBingUrl(inTrackInfo);
case MAP_SOURCE_PEAKFINDER:
case MAP_SOURCE_GEOHACK:
case MAP_SOURCE_INLINESKATE:
return generateUrlForPoint(inSource, inTrackInfo);
case MAP_SOURCE_GRAPHHOPPER:
return generateGraphHopperUrl(inTrackInfo);
case MAP_SOURCE_OSM:
default:
return generateOpenStreetMapUrl(inTrackInfo);
......@@ -155,6 +160,52 @@ public abstract class UrlGenerator
return url;
}
/**
* Generate a url for routing with GraphHopper
* @param inTrackInfo track information
* @return URL
*/
private static String generateGraphHopperUrl(TrackInfo inTrackInfo)
{
// Check if any data to display
if (inTrackInfo != null && inTrackInfo.getTrack() != null && inTrackInfo.getTrack().getNumPoints() >= 2)
{
if (inTrackInfo.getTrack().getNumPoints() == 2)
{
// Use first and last point of track
return generateGraphHopperUrl(inTrackInfo.getTrack().getPoint(0),
inTrackInfo.getTrack().getPoint(1));
}
else if (inTrackInfo.getSelection().hasRangeSelected())
{
// Use first and last point of selection
final int startIndex = inTrackInfo.getSelection().getStart();
final int endIndex = inTrackInfo.getSelection().getEnd();
return generateGraphHopperUrl(inTrackInfo.getTrack().getPoint(startIndex),
inTrackInfo.getTrack().getPoint(endIndex));
}
}
return null;
}
/**
* Generate a url for routing with GraphHopper
* @param inStartPoint start point of routing
* @param inEndPoint end point of routing
* @return URL
*/
private static String generateGraphHopperUrl(DataPoint inStartPoint, DataPoint inEndPoint)
{
final String url = "https://graphhopper.com/maps/"
+ "?point=" + FIVE_DP.format(inStartPoint.getLatitude().getDouble())
+ "%2C" + FIVE_DP.format(inStartPoint.getLongitude().getDouble())
+ "&point=" + FIVE_DP.format(inEndPoint.getLatitude().getDouble())
+ "%2C" + FIVE_DP.format(inEndPoint.getLongitude().getDouble())
+ "&locale=" + I18nManager.getText("wikipedia.lang")
+ "&elevation=true&weighting=fastest";
return url;
}
/**
* Generate a url for Open Street Map
* @param inTrackInfo track information
......@@ -207,6 +258,8 @@ public abstract class UrlGenerator
return generatePeakfinderUrl(currPoint);
case MAP_SOURCE_GEOHACK:
return generateGeohackUrl(currPoint);
case MAP_SOURCE_INLINESKATE:
return generateInlinemapUrl(currPoint);
default:
return null;
}
......@@ -220,7 +273,7 @@ public abstract class UrlGenerator
*/
private static String generatePeakfinderUrl(DataPoint inPoint)
{
return "http://peakfinder.org/?lat=" + FIVE_DP.format(inPoint.getLatitude().getDouble())
return "https://www.peakfinder.org/?lat=" + FIVE_DP.format(inPoint.getLatitude().getDouble())
+ "&lng=" + FIVE_DP.format(inPoint.getLongitude().getDouble());
}
......@@ -233,9 +286,19 @@ public abstract class UrlGenerator
{
return "https://tools.wmflabs.org/geohack/geohack.php?params=" + FIVE_DP.format(inPoint.getLatitude().getDouble())
+ "_N_" + FIVE_DP.format(inPoint.getLongitude().getDouble()) + "_E";
// TODO: Could use absolute values and S, W but this seems to work
// Note: Could use absolute values and S, W but this seems to work
}
/**
* Generate a url for Inlinemap.net
* @param inPoint current point, not null
* @return URL
*/
private static String generateInlinemapUrl(DataPoint inPoint)
{
return "http://www.inlinemap.net/en/?tab=new#/z14/" + FIVE_DP.format(inPoint.getLatitude().getDouble())
+ "," + FIVE_DP.format(inPoint.getLongitude().getDouble()) + "/terrain";
}
/**
* Get the median value from the given lat/long range
......
......@@ -8,6 +8,8 @@ import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
......@@ -51,6 +53,7 @@ public class PointEditor
private Track _track = null;
private DataPoint _point = null;
private EditFieldsTableModel _model = null;
private JButton _cancelButton = null;
private int _prevRowIndex = -1;
......@@ -95,6 +98,7 @@ public class PointEditor
public void run() {
_valueField.setVisible(false);
_valueAreaPane.setVisible(false);
_cancelButton.requestFocus();
}
});
_dialog.setVisible(true);
......@@ -176,14 +180,19 @@ public class PointEditor
// Bottom panel for OK, cancel buttons
JPanel lowerPanel = new JPanel();
lowerPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
JButton cancelButton = new JButton(I18nManager.getText("button.cancel"));
cancelButton.addActionListener(new ActionListener() {
_cancelButton = new JButton(I18nManager.getText("button.cancel"));
_cancelButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
_dialog.dispose();
}
});
lowerPanel.add(cancelButton);
_cancelButton.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent inE) {
if (inE.getKeyCode() == KeyEvent.VK_ESCAPE) {_dialog.dispose();}
}
});
lowerPanel.add(_cancelButton);
JButton okButton = new JButton(I18nManager.getText("button.ok"));
okButton.addActionListener(okListener);
lowerPanel.add(okButton);
......
......@@ -88,6 +88,7 @@ public class MenuManager implements DataSubscriber
private JCheckBoxMenuItem _mapCheckbox = null;
private JMenuItem _show3dItem = null;
private JMenu _browserMapMenu = null;
private JMenuItem _routingGraphHopperItem = null;
private JMenuItem _chartItem = null;
private JMenuItem _getGpsiesItem = null;
private JMenuItem _uploadGpsiesItem = null;
......@@ -279,6 +280,10 @@ public class MenuManager implements DataSubscriber
_browserMapMenu.add(yahooMapsItem);
JMenuItem bingMapsItem = makeMenuItem(new WebMapFunction(_app, UrlGenerator.WebService.MAP_SOURCE_BING, "menu.view.browser.bing"));
_browserMapMenu.add(bingMapsItem);
JMenuItem inlineMapItem = makeMenuItem(new WebMapFunction(_app, UrlGenerator.WebService.MAP_SOURCE_INLINESKATE, "menu.view.browser.inlinemap"));
_browserMapMenu.add(inlineMapItem);
_routingGraphHopperItem = makeMenuItem(new WebMapFunction(_app, UrlGenerator.WebService.MAP_SOURCE_GRAPHHOPPER, "menu.view.browser.graphhopper"));
_browserMapMenu.add(_routingGraphHopperItem);
onlineMenu.add(_browserMapMenu);
// wikipedia
_nearbyWikipediaItem = makeMenuItem(FunctionLibrary.FUNCTION_NEARBY_WIKIPEDIA, false);
......@@ -327,7 +332,7 @@ public class MenuManager implements DataSubscriber
trackMenu.add(_clearUndoItem);
trackMenu.addSeparator();
_compressItem = makeMenuItem(FunctionLibrary.FUNCTION_COMPRESS, false);
setShortcut(_compressItem, "shortcut.menu.edit.compress");
setShortcut(_compressItem, "shortcut.menu.track.compress");
trackMenu.add(_compressItem);
_markRectangleItem = new JMenuItem(I18nManager.getText("menu.track.markrectangle"));
_markRectangleItem.addActionListener(new ActionListener() {
......@@ -465,6 +470,7 @@ public class MenuManager implements DataSubscriber
};
_editPointItem.addActionListener(_editPointAction);
_editPointItem.setEnabled(false);
setShortcut(_editPointItem, "shortcut.menu.point.edit");
pointMenu.add(_editPointItem);
_editWaypointNameItem = makeMenuItem(FunctionLibrary.FUNCTION_EDIT_WAYPOINT_NAME, false);
pointMenu.add(_editWaypointNameItem);
......@@ -962,6 +968,8 @@ public class MenuManager implements DataSubscriber
|| _selection.getCurrentPointIndex() > (_selection.getEnd()+1));
_cutAndMoveItem.setEnabled(canCutAndMove);
_cutAndMoveButton.setEnabled(canCutAndMove);
final boolean isTrackLengthTwo = hasData && _track.getNumPoints() == 2;
_routingGraphHopperItem.setEnabled(isTrackLengthTwo || (hasData && hasRange));
// Has the map been switched on/off?
boolean mapsOn = Config.getConfigBoolean(Config.KEY_SHOW_MAP);
if (_mapCheckbox.isSelected() != mapsOn) {
......
......@@ -211,6 +211,7 @@ public class SelectorDisplay extends GenericDisplay
{
_trackpointsLabel.setText(I18nManager.getText("details.notrack"));
_filenameLabel.setText("");
_filenameLabel.setToolTipText("");
}
else
{
......@@ -219,14 +220,22 @@ public class SelectorDisplay extends GenericDisplay
int numFiles = _trackInfo.getFileInfo().getNumFiles();
if (numFiles == 1)
{
final String filenameString = _trackInfo.getFileInfo().getFilename();
_filenameLabel.setText(I18nManager.getText("details.track.file") + ": "
+ _trackInfo.getFileInfo().getFilename());
+ filenameString);
_filenameLabel.setToolTipText(filenameString);
}
else if (numFiles > 1)
{
_filenameLabel.setText(I18nManager.getText("details.track.numfiles") + ": " + numFiles);
final String labelText = I18nManager.getText("details.track.numfiles") + ": " + numFiles;
_filenameLabel.setText(labelText);
_filenameLabel.setToolTipText(labelText);
}
else
{
_filenameLabel.setText("");
_filenameLabel.setToolTipText("");
}
else _filenameLabel.setText("");
}
// Update scroller settings
......
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
......@@ -39,6 +39,110 @@ public class ProfileChart extends GenericDisplay implements MouseListener
}
}
/** Inner class to remember a single index */
class PointIndex
{
public int index = -1;
public boolean hasValue = false;
public PointIndex()
{
index = -1;
hasValue = false;
}
/** Set a single value */
public void set(int inValue)
{
index = inValue;
hasValue = (inValue != -1);
}
/** Add an index to the minimum calculation */
public void setMin(PointIndex other)
{
if (!other.hasValue) {return;}
if (!hasValue) {
index = other.index;
hasValue = other.hasValue;
}
else {
index = Math.min(index, other.index);
}
}
/** Add an index to the maximum calculation */
public void setMax(PointIndex other)
{
if (!other.hasValue) {return;}
if (!hasValue) {
index = other.index;
hasValue = other.hasValue;
}
else {
index = Math.max(index, other.index);
}
}
/** @return true if two Indexes are equal */
public boolean equals(PointIndex other)
{
if (!hasValue || !other.hasValue) {
return hasValue == other.hasValue;
}
return index == other.index;
}
}
/** Inner class to remember previous chart parameters */
class ChartParameters
{
public PointIndex selectedPoint = new PointIndex();
public PointIndex rangeStart = new PointIndex(), rangeEnd = new PointIndex();
public void clear()
{
selectedPoint.hasValue = false;
rangeStart.hasValue = false;
rangeEnd.hasValue = false;
}
/** Get the minimum index which has changed between two sets of parameters */
public int getMinChangedIndex(ChartParameters other)
{
PointIndex minIndex = new PointIndex();
if (!selectedPoint.equals(other.selectedPoint)) {
minIndex.setMin(selectedPoint);
minIndex.setMin(other.selectedPoint);
}
if (!rangeStart.equals(other.rangeStart)) {
minIndex.setMin(rangeStart);
minIndex.setMin(other.rangeStart);
}
if (!rangeEnd.equals(other.rangeEnd)) {
minIndex.setMin(rangeEnd);
minIndex.setMin(other.rangeEnd);
}
return minIndex.index;
}
/** Get the maximum index which has changed between two sets of parameters */
public int getMaxChangedIndex(ChartParameters other)
{
PointIndex maxIndex = new PointIndex();
if (!selectedPoint.equals(other.selectedPoint)) {
maxIndex.setMax(selectedPoint);
maxIndex.setMax(other.selectedPoint);
}
if (!rangeStart.equals(other.rangeStart)) {
maxIndex.setMax(rangeStart);
maxIndex.setMax(other.rangeStart);
}
if (!rangeEnd.equals(other.rangeEnd)) {
maxIndex.setMax(rangeEnd);
maxIndex.setMax(other.rangeEnd);
}
return maxIndex.index;
}
/** @return true if the parameters are completely empty (cleared) */
public boolean isEmpty()
{
return !selectedPoint.hasValue && !rangeStart.hasValue && !rangeEnd.hasValue;
}
}
/** Current scale factor in x direction*/
private double _xScaleFactor = 0.0;
/** Data to show on chart */
......@@ -47,6 +151,8 @@ public class ProfileChart extends GenericDisplay implements MouseListener
private JLabel _label = null;
/** Right-click popup menu */
private JPopupMenu _popup = null;
/** Parameters last time chart was drawn */
private ChartParameters _previousParameters = new ChartParameters();
/** Possible scales to use */
private static final int[] LINE_SCALES = {10000, 5000, 2000, 1000, 500, 200, 100, 50, 10, 5, 2, 1};
......@@ -94,141 +200,146 @@ public class ProfileChart extends GenericDisplay implements MouseListener
Config.getConfigBoolean(Config.KEY_ANTIALIAS) ? RenderingHints.VALUE_ANTIALIAS_ON : RenderingHints.VALUE_ANTIALIAS_OFF);
ColourScheme colourScheme = Config.getColourScheme();
paintBackground(g, colourScheme);
if (_track != null && _track.getNumPoints() > 0)
if (_track == null || _track.getNumPoints() <= 0)
{
_label.setText(_data.getLabel());
int width = getWidth();
int height = getHeight();
// Set up colours
final Color barColour = colourScheme.getColour(ColourScheme.IDX_POINT);
final Color rangeColour = colourScheme.getColour(ColourScheme.IDX_SELECTION);
final Color currentColour = colourScheme.getColour(ColourScheme.IDX_PRIMARY);
final Color secondColour = colourScheme.getColour(ColourScheme.IDX_SECONDARY);
final Color lineColour = colourScheme.getColour(ColourScheme.IDX_LINES);
// message if no data for the current field in track
if (!_data.hasData())
{
g.setColor(lineColour);
g.drawString(I18nManager.getText(_data.getNoDataKey()), 50, (height+_label.getHeight())/2);
paintChildren(g);
return;
}
return;
}
// Find minimum and maximum values to plot
double minValue = _data.getMinValue();
double maxValue = _data.getMaxValue();
if (maxValue <= minValue) {maxValue = minValue + 1; minValue--;}
final int numPoints = _track.getNumPoints();
_xScaleFactor = 1.0 * (width - 2 * BORDER_WIDTH - 1) / numPoints;
int usableHeight = height - 2 * BORDER_WIDTH - _label.getHeight();
double yScaleFactor = 1.0 * usableHeight / (maxValue - minValue);
int barWidth = (int) (_xScaleFactor + 1.0);
int selectedPoint = _trackInfo.getSelection().getCurrentPointIndex();
// selection start, end
int selectionStart = -1, selectionEnd = -1;
if (_trackInfo.getSelection().hasRangeSelected()) {
selectionStart = _trackInfo.getSelection().getStart();
selectionEnd = _trackInfo.getSelection().getEnd();
}
_label.setText(_data.getLabel());
int width = getWidth();
int height = getHeight();
// horizontal lines for scale - set to round numbers eg 500
int lineScale = getLineScale(minValue, maxValue);
double scaleValue = Math.ceil(minValue/lineScale) * lineScale;
int x = 0, y = 0;
final int zeroY = height - BORDER_WIDTH - (int) (yScaleFactor * (0.0 - minValue));
// Set up colours
final Color barColour = colourScheme.getColour(ColourScheme.IDX_POINT);
final Color rangeColour = colourScheme.getColour(ColourScheme.IDX_SELECTION);
final Color currentColour = colourScheme.getColour(ColourScheme.IDX_PRIMARY);
final Color secondColour = colourScheme.getColour(ColourScheme.IDX_SECONDARY);
final Color lineColour = colourScheme.getColour(ColourScheme.IDX_LINES);
double value = 0.0;
// message if no data for the current field in track
if (!_data.hasData())
{
g.setColor(lineColour);
if (lineScale >= 1)
{
while (scaleValue < maxValue)
{
y = height - BORDER_WIDTH - (int) (yScaleFactor * (scaleValue - minValue));
g.drawLine(BORDER_WIDTH + 1, y, width - BORDER_WIDTH - 1, y);
scaleValue += lineScale;
}
}
else if (minValue < 0.0)
g.drawString(I18nManager.getText(_data.getNoDataKey()), 50, (height+_label.getHeight())/2);
paintChildren(g);
return;
}
// Find minimum and maximum values to plot
double minValue = _data.getMinValue();
double maxValue = _data.getMaxValue();
if (maxValue <= minValue) {maxValue = minValue + 1; minValue--;}
final int numPoints = _track.getNumPoints();
_xScaleFactor = 1.0 * (width - 2 * BORDER_WIDTH - 1) / numPoints;
int usableHeight = height - 2 * BORDER_WIDTH - _label.getHeight();
double yScaleFactor = 1.0 * usableHeight / (maxValue - minValue);
int barWidth = (int) (_xScaleFactor + 1.0);
int selectedPoint = _trackInfo.getSelection().getCurrentPointIndex();
// selection start, end
int selectionStart = -1, selectionEnd = -1;
if (_trackInfo.getSelection().hasRangeSelected()) {
selectionStart = _trackInfo.getSelection().getStart();
selectionEnd = _trackInfo.getSelection().getEnd();
}
int y = 0;
double value = 0.0;
// horizontal lines for scale - set to round numbers eg 500
final int lineScale = getLineScale(minValue, maxValue);
double scaleValue = Math.ceil(minValue/lineScale) * lineScale;
final int zeroY = height - BORDER_WIDTH - (int) (yScaleFactor * (0.0 - minValue));
g.setColor(lineColour);
if (lineScale >= 1)
{
while (scaleValue < maxValue)
{
// just draw zero line
y = zeroY;
y = height - BORDER_WIDTH - (int) (yScaleFactor * (scaleValue - minValue));
g.drawLine(BORDER_WIDTH + 1, y, width - BORDER_WIDTH - 1, y);
scaleValue += lineScale;
}
}
else if (minValue < 0.0)
{
// just draw zero line
y = zeroY;
g.drawLine(BORDER_WIDTH + 1, y, width - BORDER_WIDTH - 1, y);
}
try
try
{
// loop through points
g.setColor(barColour);
for (int p = 0; p < numPoints; p++)
{
// loop through points
g.setColor(barColour);
for (int p = 0; p < numPoints; p++)
{
x = (int) (_xScaleFactor * p) + 1;
if (p == selectionStart)
g.setColor(rangeColour);
else if (p == (selectionEnd+1))
g.setColor(barColour);
if (_data.hasData(p))
{
value = _data.getData(p);
// Normal case is the minimum value greater than zero
if (minValue >= 0)
{
y = (int) (yScaleFactor * (value - minValue));
g.fillRect(BORDER_WIDTH+x, height-BORDER_WIDTH - y, barWidth, y);
}
else if (value >= 0.0) {
// Bar upwards from the zero line
y = height-BORDER_WIDTH - (int) (yScaleFactor * (value - minValue));
g.fillRect(BORDER_WIDTH+x, y, barWidth, zeroY - y);
}
else {
// Bar downwards from the zero line
int barHeight = (int) (yScaleFactor * value);
g.fillRect(BORDER_WIDTH+x, zeroY, barWidth, -barHeight);
}
}
}
// current point (make sure it's drawn last)
if (selectedPoint >= 0)
if (p == selectionStart)
g.setColor(rangeColour);
else if (p == (selectionEnd+1))
g.setColor(barColour);
final int x = (int) (_xScaleFactor * p) + 1;
if (_data.hasData(p))
{
x = (int) (_xScaleFactor * selectedPoint) + 1;
g.setColor(secondColour);
g.fillRect(BORDER_WIDTH + x, height-usableHeight-BORDER_WIDTH+1, barWidth, usableHeight-2);
if (_data.hasData(selectedPoint))
value = _data.getData(p);
// Normal case is the minimum value greater than zero
if (minValue >= 0)
{
g.setColor(currentColour);
value = _data.getData(selectedPoint);
y = (int) (yScaleFactor * (value - minValue));
g.fillRect(BORDER_WIDTH + x, height-BORDER_WIDTH - y, barWidth, y);
g.fillRect(BORDER_WIDTH+x, height-BORDER_WIDTH - y, barWidth, y);
}
else if (value >= 0.0) {
// Bar upwards from the zero line
y = height-BORDER_WIDTH - (int) (yScaleFactor * (value - minValue));
g.fillRect(BORDER_WIDTH+x, y, barWidth, zeroY - y);
}
else {
// Bar downwards from the zero line
int barHeight = (int) (yScaleFactor * value);
g.fillRect(BORDER_WIDTH+x, zeroY, barWidth, -barHeight);
}
}
}
catch (NullPointerException npe) { // ignore, probably due to data being changed
}
// Draw numbers on top of the graph to mark scale
if (lineScale >= 1)
// current point (make sure it's drawn last)
if (selectedPoint >= 0)
{
int textHeight = g.getFontMetrics().getHeight();
scaleValue = (int) (minValue / lineScale + 1) * lineScale;
if (minValue < 0.0) {scaleValue -= lineScale;}
y = 0;
g.setColor(currentColour);
while (scaleValue < maxValue)
final int sel_x = (int) (_xScaleFactor * selectedPoint) + 1;
g.setColor(secondColour);
g.fillRect(BORDER_WIDTH + sel_x, height-usableHeight-BORDER_WIDTH+1, barWidth, usableHeight-2);
if (_data.hasData(selectedPoint))
{
y = height - BORDER_WIDTH - (int) (yScaleFactor * (scaleValue - minValue));
// Limit y so String isn't above border
if (y < (BORDER_WIDTH + textHeight)) {
y = BORDER_WIDTH + textHeight;
}
g.drawString(""+(int)scaleValue, BORDER_WIDTH + 5, y);
scaleValue += lineScale;
g.setColor(currentColour);
value = _data.getData(selectedPoint);
y = (int) (yScaleFactor * (value - minValue));
g.fillRect(BORDER_WIDTH + sel_x, height-BORDER_WIDTH - y, barWidth, y);
}
}
// Paint label on top
paintChildren(g);
}
catch (NullPointerException npe) { // ignore, probably due to data being changed
}
// Draw numbers on top of the graph to mark scale
if (lineScale >= 1)
{
int textHeight = g.getFontMetrics().getHeight();
scaleValue = (int) (minValue / lineScale + 1) * lineScale;
if (minValue < 0.0) {scaleValue -= lineScale;}
y = 0;
g.setColor(currentColour);
while (scaleValue < maxValue)
{
y = height - BORDER_WIDTH - (int) (yScaleFactor * (scaleValue - minValue));
// Limit y so String isn't above border
if (y < (BORDER_WIDTH + textHeight)) {
y = BORDER_WIDTH + textHeight;
}
g.drawString(""+(int)scaleValue, BORDER_WIDTH + 5, y);
scaleValue += lineScale;
}
}
// Paint label on top
paintChildren(g);
}
......@@ -254,7 +365,8 @@ public class ProfileChart extends GenericDisplay implements MouseListener
inG.setColor(COLOR_NODATA_TEXT);
inG.drawString(I18nManager.getText("display.nodata"), 50, height/2);
}
else {
else
{
inG.setColor(borderColour);
inG.drawRect(BORDER_WIDTH, BORDER_WIDTH + _label.getHeight(),
width - 2*BORDER_WIDTH, height-2*BORDER_WIDTH-_label.getHeight());
......@@ -337,14 +449,49 @@ public class ProfileChart extends GenericDisplay implements MouseListener
public void dataUpdated(byte inUpdateType)
{
// Try not to recalculate all the values unless necessary
if (inUpdateType != SELECTION_CHANGED) {
if (inUpdateType != SELECTION_CHANGED)
{
_data.init(Config.getUnitSet());
_previousParameters.clear();
}
// Update the menu if necessary
if ((inUpdateType & DATA_ADDED_OR_REMOVED) > 0) {
makePopup();
}
repaint();
if (inUpdateType == SELECTION_CHANGED) {
triggerPartialRepaint();
}
else
{
repaint();
}
}
/**
* For performance reasons, only repaint the part of the graphics affected by
* the change in selection
*/
private void triggerPartialRepaint()
{
ChartParameters currentParameters = new ChartParameters();
currentParameters.selectedPoint.set(_trackInfo.getSelection().getCurrentPointIndex());
if (_trackInfo.getSelection().hasRangeSelected())
{
currentParameters.rangeStart.set(_trackInfo.getSelection().getStart());
currentParameters.rangeEnd.set(_trackInfo.getSelection().getEnd());
}
int minPointIndex = currentParameters.getMinChangedIndex(_previousParameters);
minPointIndex = Math.max(minPointIndex, 0);
int maxPointIndex = currentParameters.getMaxChangedIndex(_previousParameters);
if (maxPointIndex < minPointIndex) {
maxPointIndex = _trackInfo.getTrack().getNumPoints() - 1;
}
// System.out.println("Redraw from index: " + minPointIndex + " to " + maxPointIndex);
_previousParameters = currentParameters;
final int region_x = (int) (_xScaleFactor * minPointIndex) + BORDER_WIDTH;
final int region_width = (int) (_xScaleFactor * (maxPointIndex-minPointIndex+2)) + 2;
repaint(region_x, 0, region_width, getHeight());
}
/**
......
......@@ -70,8 +70,9 @@ shortcut.menu.file.open=O
shortcut.menu.file.load=L
shortcut.menu.file.save=S
shortcut.menu.track.undo=Z
shortcut.menu.edit.compress=C
shortcut.menu.track.compress=C
shortcut.menu.range.all=A
shortcut.menu.point.edit=R
shortcut.menu.help.help=H
## Functions
......
......@@ -71,8 +71,9 @@ shortcut.menu.file.open=O
shortcut.menu.file.load=N
shortcut.menu.file.save=U
shortcut.menu.track.undo=U
shortcut.menu.edit.compress=K
shortcut.menu.track.compress=K
shortcut.menu.range.all=V
shortcut.menu.point.edit=E
shortcut.menu.help.help=P
# Functions
......
......@@ -68,8 +68,9 @@ shortcut.menu.file.open=O
shortcut.menu.file.load=L
shortcut.menu.file.save=S
shortcut.menu.track.undo=Z
shortcut.menu.edit.compress=K
shortcut.menu.track.compress=K
shortcut.menu.range.all=A
shortcut.menu.point.edit=B
shortcut.menu.help.help=H
# Functions
......
......@@ -70,8 +70,9 @@ shortcut.menu.file.open=O
shortcut.menu.file.load=L
shortcut.menu.file.save=S
shortcut.menu.track.undo=Z
shortcut.menu.edit.compress=K
shortcut.menu.track.compress=K
shortcut.menu.range.all=A
shortcut.menu.point.edit=E
shortcut.menu.help.help=H
# Functions
......@@ -561,7 +562,7 @@ dialog.displaysettings.wpicon.default=P\u00fcnktli
dialog.displaysettings.wpicon.ringpt=Rundes Schild
dialog.displaysettings.wpicon.plectrum=Plektrum
dialog.displaysettings.wpicon.ring=Chreis
dialog.displaysettings.wpicon.pin=Sto\u00dfnadel
dialog.displaysettings.wpicon.pin=Stossnadeli
dialog.displaysettings.size.small=Chli
dialog.displaysettings.size.medium=Mittel
dialog.displaysettings.size.large=Gross
......