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;
......
......@@ -13,8 +13,11 @@ public abstract class GradientCalculator
* @param inValue object in which to place result of calculation
*/
public static void calculateGradient(Track inTrack, int inIndex, SpeedValue inValue)
{
if (inValue != null)
{
inValue.setInvalid();
}
if (inTrack == null || inIndex < 0 || inValue == null)
{
System.err.println("Cannot calculate gradient for index " + inIndex);
......
......@@ -15,8 +15,11 @@ public abstract class SpeedCalculator
* @param inValue object in which to place result of calculation
*/
public static void calculateSpeed(Track inTrack, int inIndex, SpeedValue inValue)
{
if (inValue != null)
{
inValue.setInvalid();
}
if (inTrack == null || inIndex < 0 || inValue == null)
{
System.err.println("Cannot calculate speed for index " + inIndex);
......
......@@ -191,8 +191,7 @@ 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
......@@ -220,7 +219,6 @@ public class GetWikipediaFunction extends GenericDownloaderFunction
}
_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)
{
......
......@@ -31,6 +31,8 @@ public abstract class UrlGenerator
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,8 +200,12 @@ 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)
{
return;
}
_label.setText(_data.getLabel());
int width = getWidth();
int height = getHeight();
......@@ -134,13 +244,13 @@ public class ProfileChart extends GenericDisplay implements MouseListener
selectionEnd = _trackInfo.getSelection().getEnd();
}
int y = 0;
double value = 0.0;
// horizontal lines for scale - set to round numbers eg 500
int lineScale = getLineScale(minValue, maxValue);
final 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));
double value = 0.0;
g.setColor(lineColour);
if (lineScale >= 1)
{
......@@ -164,11 +274,12 @@ public class ProfileChart extends GenericDisplay implements MouseListener
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);
final int x = (int) (_xScaleFactor * p) + 1;
if (_data.hasData(p))
{
value = _data.getData(p);
......@@ -190,18 +301,19 @@ public class ProfileChart extends GenericDisplay implements MouseListener
}
}
}
// current point (make sure it's drawn last)
if (selectedPoint >= 0)
{
x = (int) (_xScaleFactor * selectedPoint) + 1;
final int sel_x = (int) (_xScaleFactor * selectedPoint) + 1;
g.setColor(secondColour);
g.fillRect(BORDER_WIDTH + x, height-usableHeight-BORDER_WIDTH+1, barWidth, usableHeight-2);
g.fillRect(BORDER_WIDTH + sel_x, height-usableHeight-BORDER_WIDTH+1, barWidth, usableHeight-2);
if (_data.hasData(selectedPoint))
{
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 + sel_x, height-BORDER_WIDTH - y, barWidth, y);
}
}
}
......@@ -229,7 +341,6 @@ public class ProfileChart extends GenericDisplay implements MouseListener
// 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,15 +449,50 @@ 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();
}
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());
}
/**
* React to click on profile display
......
......@@ -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
......