--- /dev/null
+*.class
+*.jar
+set -e
# Build script
# Version number
PRUNENAME=gpsprune_19.2
{
// Instance variables
private JFrame _frame = null;
+ private String _titlePrefix = null;
private Track _track = null;
private TrackInfo _trackInfo = null;
private int _lastSavePosition = 0;
public App(JFrame inFrame)
{
_frame = inFrame;
+ _titlePrefix = _frame.getTitle();
_undoStack = new UndoStack();
_track = new Track();
_trackInfo = new TrackInfo(_track);
}
+ /**
+ * Remove altitudes from selected points
+ */
+ public void removeAltitudes(int selStart, int selEnd)
+ {
+ UndoRemoveAltitudes undo = new UndoRemoveAltitudes(_trackInfo, selStart, selEnd);
+ if (_trackInfo.getTrack().removeAltitudes(selStart, selEnd))
+ {
+ _undoStack.add(undo);
+ _trackInfo.getSelection().markInvalid();
+ UpdateMessageBroker.informSubscribers(DataSubscriber.DATA_EDITED);
+ UpdateMessageBroker.informSubscribers(I18nManager.getText("confirm.removealtitudes"));
+ }
+ }
+
+
/**
* Merge the track segments within the current selection
*/
+ " '" + inSourceInfo.getName() + "'");
// update menu
_menuManager.informFileLoaded();
+ // recentre viewport on new file data
+ _viewport.recentreViewport();
+ // update main window title
+ updateTitle();
// Remove busy lock
_busyLoading = false;
// load next file if there's a queue
public void setCurrentMode(AppMode inMode) {
_appMode = inMode;
}
+
+ /** Update main window title **/
+ public void updateTitle() {
+ ArrayList<String> filenames = _trackInfo.getFileInfo().getFilenames();
+ if (filenames.size() > 0) {
+ _frame.setTitle(_titlePrefix + ": " + String.join(", ", filenames));
+ }
+ else
+ {
+ _frame.setTitle(_titlePrefix);
+ }
+ }
}
import tim.prune.function.PlayAudioFunction;
import tim.prune.function.RearrangePhotosFunction;
import tim.prune.function.RearrangeWaypointsFunction;
+import tim.prune.function.RemoveAltitudes;
import tim.prune.function.RemoveAudioFunction;
import tim.prune.function.RemovePhotoFunction;
import tim.prune.function.RotatePhoto;
public static GenericFunction FUNCTION_DOWNLOAD_OSM = null;
public static GenericFunction FUNCTION_ADD_TIME_OFFSET = null;
public static GenericFunction FUNCTION_ADD_ALTITUDE_OFFSET = null;
+ public static GenericFunction FUNCTION_REMOVE_ALTITUDES = null;
public static GenericFunction FUNCTION_CONVERT_NAMES_TO_TIMES = null;
public static GenericFunction FUNCTION_DELETE_FIELD_VALUES = null;
public static GenericFunction FUNCTION_PASTE_COORDINATES = null;
FUNCTION_DOWNLOAD_OSM = new DownloadOsmFunction(inApp);
FUNCTION_ADD_TIME_OFFSET = new AddTimeOffset(inApp);
FUNCTION_ADD_ALTITUDE_OFFSET = new AddAltitudeOffset(inApp);
+ FUNCTION_REMOVE_ALTITUDES = new RemoveAltitudes(inApp);
FUNCTION_CONVERT_NAMES_TO_TIMES = new ConvertNamesToTimes(inApp);
FUNCTION_DELETE_FIELD_VALUES = new DeleteFieldValues(inApp);
FUNCTION_PASTE_COORDINATES = new PasteCoordinates(inApp);
}
}
+ /**
+ * Remove altitude from point
+ */
+ public void removeAltitude()
+ {
+ _altitude = Altitude.NONE;
+ _fieldValues[_fieldList.getFieldIndex(Field.ALTITUDE)] = _altitude.getStringValue(null);
+ setModified(false);
+ }
+
/**
* Reset the altitude to the previous value (by an undo)
* @param inClone altitude object cloned from earlier
return "";
}
+ /**
+ * @return The source names
+ */
+ public ArrayList<String> getFilenames()
+ {
+ ArrayList<String> filenames = new ArrayList<String>();
+ for (SourceInfo source : _sources)
+ {
+ filenames.add(source.getName());
+ }
+ return filenames;
+ }
+
/**
* @param inIndex index number, starting from zero
* @return source info object
}
+ /**
+ * Remove altitudes from the specified range
+ * @param inStart start of range
+ * @param inEnd end of range
+ */
+ public boolean removeAltitudes(int inStart, int inEnd)
+ {
+ // sanity check
+ if (inStart < 0 || inEnd < 0 || inStart >= inEnd || inEnd >= _numPoints) {
+ return false;
+ }
+
+ boolean anyRemoved = false;
+ for (int i=inStart; i<=inEnd; i++)
+ {
+ DataPoint p = _dataPoints[i];
+ if (p != null && p.hasAltitude())
+ {
+ p.removeAltitude();
+ anyRemoved = true;
+ }
+ }
+ return anyRemoved;
+ }
+
/**
* Interleave all waypoints by each nearest track point
* @return true if successful, false if no change
--- /dev/null
+package tim.prune.function;
+
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseAdapter;
+
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+import tim.prune.App;
+import tim.prune.GenericFunction;
+import tim.prune.I18nManager;
+import tim.prune.config.Config;
+import tim.prune.data.Field;
+import tim.prune.data.Unit;
+import tim.prune.data.UnitSetLibrary;
+
+/**
+ * Class to provide the function to add remove the altitude from points in a
+ * track range
+ */
+public class RemoveAltitudes extends GenericFunction
+{
+ /**
+ * Constructor
+ * @param inApp application object for callback
+ */
+ public RemoveAltitudes(App inApp)
+ {
+ super(inApp);
+ }
+
+ /** Get the name key */
+ public String getNameKey() {
+ return "function.removealtitudes";
+ }
+
+ /**
+ * Begin the function
+ */
+ public void begin()
+ {
+ int selStart = _app.getTrackInfo().getSelection().getStart();
+ int selEnd = _app.getTrackInfo().getSelection().getEnd();
+ if (!_app.getTrackInfo().getTrack().hasData(Field.ALTITUDE, selStart, selEnd))
+ {
+ _app.showErrorMessage(getNameKey(), "dialog.addaltitude.noaltitudes");
+ return;
+ }
+ _app.removeAltitudes(selStart, selEnd);
+ }
+}
if (_model.getChanged(i))
{
Field field = fieldList.getField(i);
+ if (field == field.WAYPT_NAME) {
+ if (wasNameAdded(_model.getValue(i))) {
+ _app.createPoint(_point.clonePoint());
+ }
+ }
editList.addEdit(new FieldEdit(field, _model.getValue(i)));
undoList.addEdit(new FieldEdit(field, _point.getFieldValue(field)));
}
}
_app.completePointEdit(editList, undoList);
}
+
+ private boolean wasNameAdded(String newName)
+ {
+ String prevName = _point.getWaypointName();
+ boolean prevNull = (prevName == null || prevName.equals(""));
+ boolean newNull = (newName == null || newName.equals(""));
+ return (prevNull && !newNull);
+ }
}
// Check whether name has really changed
if (hasNameChanged())
{
- // Make lists for edit and undo, and add the changed field
+ // If a new name has been added, changing the point
+ // from trackpoint to waypoint, duplicate it
+ if (wasNameAdded())
+ {
+ _app.createPoint(_point.clonePoint());
+ }
+
+ // make lists for edit and undo, and add the changed field
FieldEditList editList = new FieldEditList();
FieldEditList undoList = new FieldEditList();
editList.addEdit(new FieldEdit(Field.WAYPT_NAME, _nameField.getText().trim()));
|| (!prevNull && newNull)
|| (!prevNull && !newNull && !prevName.equals(newName));
}
+
+ /**
+ * Check whether a new name has been added
+ * @return true if it has indeed
+ */
+ private boolean wasNameAdded()
+ {
+ String prevName = _point.getWaypointName();
+ String newName = _nameField.getText().trim();
+ boolean prevNull = (prevName == null || prevName.equals(""));
+ boolean newNull = (newName == null || newName.equals(""));
+ return (prevNull && !newNull);
+ }
}
if (inNumSecs < 86400L) return "" + (inNumSecs / 60 / 60) + I18nManager.getText("display.range.time.hours")
+ " " + ((inNumSecs / 60) % 60) + I18nManager.getText("display.range.time.mins");
if (inNumSecs < 432000L) return "" + (inNumSecs / 86400L) + I18nManager.getText("display.range.time.days")
- + " " + (inNumSecs / 60 / 60) % 24 + I18nManager.getText("display.range.time.hours");
+ + " " + (inNumSecs / 60 / 60) % 24 + I18nManager.getText("display.range.time.hours")
+ + " " + ((inNumSecs / 60) % 60) + I18nManager.getText("display.range.time.mins");
if (inNumSecs < 86400000L) return "" + (inNumSecs / 86400L) + I18nManager.getText("display.range.time.days");
return "big";
}
private JMenuItem _reverseItem = null;
private JMenuItem _addTimeOffsetItem = null;
private JMenuItem _addAltitudeOffsetItem = null;
+ private JMenuItem _removeAltitudesItem = null;
private JMenuItem _mergeSegmentsItem = null;
private JMenuItem _rearrangeWaypointsItem = null;
private JMenuItem _splitSegmentsItem = null;
rangeMenu.add(_addTimeOffsetItem);
_addAltitudeOffsetItem = makeMenuItem(FunctionLibrary.FUNCTION_ADD_ALTITUDE_OFFSET, false);
rangeMenu.add(_addAltitudeOffsetItem);
+ _removeAltitudesItem = makeMenuItem(FunctionLibrary.FUNCTION_REMOVE_ALTITUDES, false);
+ rangeMenu.add(_removeAltitudesItem);
_mergeSegmentsItem = new JMenuItem(I18nManager.getText("menu.range.mergetracksegments"));
_mergeSegmentsItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
_reverseItem.setEnabled(hasRange);
_addTimeOffsetItem.setEnabled(hasRange);
_addAltitudeOffsetItem.setEnabled(hasRange);
+ _removeAltitudesItem.setEnabled(hasRange);
_convertNamesToTimesItem.setEnabled(hasRange && _track.hasWaypoints());
_deleteFieldValuesItem.setEnabled(hasRange);
_fullRangeDetailsItem.setEnabled(hasRange);
else if (numFiles > 1)
{
final String labelText = I18nManager.getText("details.track.numfiles") + ": " + numFiles;
+ final String filenameString = String.join(", ", _trackInfo.getFileInfo().getFilenames());
_filenameLabel.setText(labelText);
- _filenameLabel.setToolTipText(labelText);
+ _filenameLabel.setToolTipText(filenameString);
}
else
{
double maxLon = MapUtils.getLongitudeFromX(mapPosition.getXFromPixels(width, width));
return new double[] {minLat, minLon, maxLat, maxLon};
}
+
+ /**
+ * Recentre the viewport on the data
+ */
+ public void recentreViewport()
+ {
+ _mapCanvas.zoomToFit();
+ }
}
WpIconDefinition _waypointIconDefinition = null;
/** Constant for click sensitivity when selecting nearest point */
- private static final int CLICK_SENSITIVITY = 10;
+ private static final int CLICK_SENSITIVITY = 30;
/** Constant for pan distance from key presses */
private static final int PAN_DISTANCE = 20;
/** Constant for pan distance from autopan */
// add control panels to this one
setLayout(new BorderLayout());
- _topPanel.setVisible(false);
- _sidePanel.setVisible(false);
+ _topPanel.setVisible(true);
+ _sidePanel.setVisible(true);
add(_topPanel, BorderLayout.NORTH);
add(_sidePanel, BorderLayout.WEST);
add(_scaleBar, BorderLayout.SOUTH);
/**
* Zoom to fit the current data area
*/
- private void zoomToFit()
+ public void zoomToFit()
{
+ int maxZoom = (_track.getNumPoints() == 0)?2:_tileManager.getMaxZoomLevel();
_latRange = _track.getLatRange();
_lonRange = _track.getLonRange();
_xRange = new DoubleRange(MapUtils.getXFromLongitude(_lonRange.getMinimum()),
MapUtils.getXFromLongitude(_lonRange.getMaximum()));
_yRange = new DoubleRange(MapUtils.getYFromLatitude(_latRange.getMinimum()),
MapUtils.getYFromLatitude(_latRange.getMaximum()));
- _mapPosition.zoomToXY(_xRange.getMinimum(), _xRange.getMaximum(), _yRange.getMinimum(), _yRange.getMaximum(),
- getWidth(), getHeight());
+ _mapPosition.zoomToXY(
+ _xRange.getMinimum(), _xRange.getMaximum(),
+ _yRange.getMinimum(), _yRange.getMaximum(),
+ getWidth(), getHeight(), maxZoom);
}
if (_mapImage != null && (_mapImage.getWidth() != getWidth() || _mapImage.getHeight() != getHeight())) {
_mapImage = null;
}
- if (_track.getNumPoints() > 0)
+ // Check for autopan if enabled / necessary
+ if (_autopanCheckBox.isSelected())
{
- // Check for autopan if enabled / necessary
- if (_autopanCheckBox.isSelected())
+ int selectedPoint = _selection.getCurrentPointIndex();
+ if (selectedPoint >= 0 && _dragFromX == -1 && selectedPoint != _prevSelectedPoint)
{
- int selectedPoint = _selection.getCurrentPointIndex();
- if (selectedPoint >= 0 && _dragFromX == -1 && selectedPoint != _prevSelectedPoint)
- {
- autopanToPoint(selectedPoint);
- }
- _prevSelectedPoint = selectedPoint;
+ autopanToPoint(selectedPoint);
}
+ _prevSelectedPoint = selectedPoint;
+ }
- // Draw the map contents if necessary
- if (_mapImage == null || _recalculate)
- {
- paintMapContents();
- _scaleBar.updateScale(_mapPosition.getZoom(), _mapPosition.getYFromPixels(0, 0));
- }
- // Draw the prepared image onto the panel
- if (_mapImage != null) {
- inG.drawImage(_mapImage, 0, 0, getWidth(), getHeight(), null);
- }
+ // Draw the map contents if necessary
+ if (_mapImage == null || _recalculate)
+ {
+ paintMapContents();
+ _scaleBar.updateScale(_mapPosition.getZoom(), _mapPosition.getYFromPixels(0, 0));
+ }
+ // Draw the prepared image onto the panel
+ if (_mapImage != null) {
+ inG.drawImage(_mapImage, 0, 0, getWidth(), getHeight(), null);
+ }
- switch (_drawMode)
- {
- case MODE_DRAG_POINT:
- drawDragLines(inG, _selection.getCurrentPointIndex()-1, _selection.getCurrentPointIndex()+1);
- break;
+ switch (_drawMode)
+ {
+ case MODE_DRAG_POINT:
+ drawDragLines(inG, _selection.getCurrentPointIndex()-1, _selection.getCurrentPointIndex()+1);
+ break;
- case MODE_CREATE_MIDPOINT:
- drawDragLines(inG, _clickedPoint-1, _clickedPoint);
- break;
+ case MODE_CREATE_MIDPOINT:
+ drawDragLines(inG, _clickedPoint-1, _clickedPoint);
+ break;
- case MODE_ZOOM_RECT:
- case MODE_MARK_RECTANGLE:
- if (_dragFromX != -1 && _dragFromY != -1)
- {
- // Draw the zoom rectangle if necessary
- inG.setColor(Color.RED);
- inG.drawLine(_dragFromX, _dragFromY, _dragFromX, _dragToY);
- inG.drawLine(_dragFromX, _dragFromY, _dragToX, _dragFromY);
- inG.drawLine(_dragToX, _dragFromY, _dragToX, _dragToY);
- inG.drawLine(_dragFromX, _dragToY, _dragToX, _dragToY);
- }
- break;
-
- case MODE_DRAW_POINTS_CONT:
- // draw line to mouse position to show drawing mode
- inG.setColor(Config.getColourScheme().getColour(ColourScheme.IDX_POINT));
- int prevIndex = _track.getNumPoints()-1;
- int px = getWidth() / 2 + _mapPosition.getXFromCentre(_track.getX(prevIndex));
- int py = getHeight() / 2 + _mapPosition.getYFromCentre(_track.getY(prevIndex));
- inG.drawLine(px, py, _dragToX, _dragToY);
- break;
- }
- }
- else
- {
- inG.setColor(Config.getColourScheme().getColour(ColourScheme.IDX_BACKGROUND));
- inG.fillRect(0, 0, getWidth(), getHeight());
- inG.setColor(COLOR_MESSAGES);
- inG.drawString(I18nManager.getText("display.nodata"), 50, getHeight()/2);
- _scaleBar.updateScale(-1, 0);
+ case MODE_ZOOM_RECT:
+ case MODE_MARK_RECTANGLE:
+ if (_dragFromX != -1 && _dragFromY != -1)
+ {
+ // Draw the zoom rectangle if necessary
+ inG.setColor(Color.RED);
+ inG.drawLine(_dragFromX, _dragFromY, _dragFromX, _dragToY);
+ inG.drawLine(_dragFromX, _dragFromY, _dragToX, _dragFromY);
+ inG.drawLine(_dragToX, _dragFromY, _dragToX, _dragToY);
+ inG.drawLine(_dragFromX, _dragToY, _dragToX, _dragToY);
+ }
+ break;
+
+ case MODE_DRAW_POINTS_CONT:
+ // draw line to mouse position to show drawing mode
+ inG.setColor(Config.getColourScheme().getColour(ColourScheme.IDX_POINT));
+ int prevIndex = _track.getNumPoints()-1;
+ int px = getWidth() / 2 + _mapPosition.getXFromCentre(_track.getX(prevIndex));
+ int py = getHeight() / 2 + _mapPosition.getYFromCentre(_track.getY(prevIndex));
+ inG.drawLine(px, py, _dragToX, _dragToY);
+ break;
}
// Draw slider etc on top
paintChildren(inG);
*/
public void mouseClicked(MouseEvent inE)
{
- if (_track != null && _track.getNumPoints() > 0)
+ // select point if it's a left-click
+ if (!inE.isMetaDown())
{
- // select point if it's a left-click
- if (!inE.isMetaDown())
+ if (inE.getClickCount() == 1)
{
- if (inE.getClickCount() == 1)
+ // single click
+ if (_drawMode == MODE_DEFAULT)
{
- // single click
- if (_drawMode == MODE_DEFAULT)
+ int pointIndex = _clickedPoint;
+ if (pointIndex == INDEX_UNKNOWN)
{
- int pointIndex = _clickedPoint;
- if (pointIndex == INDEX_UNKNOWN)
- {
- // index hasn't been calculated yet
- pointIndex = _track.getNearestPointIndex(
- _mapPosition.getXFromPixels(inE.getX(), getWidth()),
- _mapPosition.getYFromPixels(inE.getY(), getHeight()),
- _mapPosition.getBoundsFromPixels(CLICK_SENSITIVITY), false);
- }
- // Extend selection for shift-click
- if (inE.isShiftDown()) {
- _trackInfo.extendSelection(pointIndex);
- }
- else {
- _trackInfo.selectPoint(pointIndex);
- }
+ // index hasn't been calculated yet
+ pointIndex = _track.getNearestPointIndex(
+ _mapPosition.getXFromPixels(inE.getX(), getWidth()),
+ _mapPosition.getYFromPixels(inE.getY(), getHeight()),
+ _mapPosition.getBoundsFromPixels(CLICK_SENSITIVITY), false);
}
- else if (_drawMode == MODE_DRAW_POINTS_START)
- {
- _app.createPoint(createPointFromClick(inE.getX(), inE.getY()));
- _dragToX = inE.getX();
- _dragToY = inE.getY();
- _drawMode = MODE_DRAW_POINTS_CONT;
+ // Extend selection for shift-click
+ if (inE.isShiftDown()) {
+ _trackInfo.extendSelection(pointIndex);
}
- else if (_drawMode == MODE_DRAW_POINTS_CONT)
- {
- DataPoint point = createPointFromClick(inE.getX(), inE.getY());
- _app.createPoint(point, false); // not a new segment
+ else {
+ _trackInfo.selectPoint(pointIndex);
}
}
- else if (inE.getClickCount() == 2)
+ else if (_drawMode == MODE_DRAW_POINTS_START)
{
- // double click
- if (_drawMode == MODE_DEFAULT) {
- panMap(inE.getX() - getWidth()/2, inE.getY() - getHeight()/2);
- zoomIn();
- }
- else if (_drawMode == MODE_DRAW_POINTS_START || _drawMode == MODE_DRAW_POINTS_CONT) {
- _drawMode = MODE_DEFAULT;
- }
+ _app.createPoint(createPointFromClick(inE.getX(), inE.getY()));
+ _dragToX = inE.getX();
+ _dragToY = inE.getY();
+ _drawMode = MODE_DRAW_POINTS_CONT;
+ }
+ else if (_drawMode == MODE_DRAW_POINTS_CONT)
+ {
+ DataPoint point = createPointFromClick(inE.getX(), inE.getY());
+ _app.createPoint(point, false); // not a new segment
}
}
- else
+ else if (inE.getClickCount() == 2)
{
- // show the popup menu for right-clicks
- _popupMenuX = inE.getX();
- _popupMenuY = inE.getY();
- _popup.show(this, _popupMenuX, _popupMenuY);
+ // double click
+ if (_drawMode == MODE_DEFAULT) {
+ panMap(inE.getX() - getWidth()/2, inE.getY() - getHeight()/2);
+ zoomIn();
+ }
+ else if (_drawMode == MODE_DRAW_POINTS_START || _drawMode == MODE_DRAW_POINTS_CONT) {
+ _drawMode = MODE_DEFAULT;
+ }
}
}
+ else
+ {
+ // show the popup menu for right-clicks
+ _popupMenuX = inE.getX();
+ _popupMenuY = inE.getY();
+ _popup.show(this, _popupMenuX, _popupMenuY);
+ }
// Reset app mode
_app.setCurrentMode(App.AppMode.NORMAL);
if (_drawMode == MODE_MARK_RECTANGLE) _drawMode = MODE_DEFAULT;
}
}
repaint();
- // enable or disable components
- boolean hasData = _track.getNumPoints() > 0;
- _topPanel.setVisible(hasData);
- _sidePanel.setVisible(hasData);
// grab focus for the key presses
this.requestFocus();
}
* @param inWidth width of display
* @param inHeight height of display
*/
- public void zoomToXY(double inMinX, double inMaxX, double inMinY, double inMaxY, int inWidth, int inHeight)
+ public void zoomToXY(double inMinX, double inMaxX, double inMinY, double inMaxY, int inWidth, int inHeight, int maxZoom)
{
// System.out.println("Zooming to " + inMinX + ", " + inMaxX + ", " + inMinY + ", " + inMaxY + "; width=" + inWidth + ", height=" + inHeight);
double diffX = Math.abs(inMaxX - inMinX);
double diffY = Math.abs(inMaxY - inMinY);
// Find out what zoom level to go to
int requiredZoom = -1;
- for (int currZoom = MAX_ZOOM; currZoom >= 2; currZoom--)
+ for (int currZoom = maxZoom; currZoom >= 2; currZoom--)
{
if (transformToPixels(diffX, currZoom) < inWidth
&& transformToPixels(diffY, currZoom) < inHeight)
urlstr = "http://" + urlstr;
}
// check trailing /
- if (!urlstr.endsWith("/")) {
+ if (!urlstr.endsWith("/") && !urlstr.contains("?")) {
urlstr = urlstr + "/";
}
// Validate current url, return null if not ok
* @return true if zoom is too high for tiles
*/
public boolean isOverzoomed()
+ {
+ return _zoom > getMaxZoomLevel();
+ }
+
+ /**
+ * @return the maximum useable zoom level for tiles
+ */
+ public int getMaxZoomLevel()
{
// Ask current map source what maximum zoom is
int maxZoom = (_mapSource == null?0:_mapSource.getMaxZoomLevel());
- return (_zoom > maxZoom);
+ return maxZoom;
+
}
/**
/**
* Make the URL to get the specified tile
+ * @param inLayerNum layer number
+ * @param inZoom zoom level
+ * @param inX x coordinate
+ * @param inY y coordinate
+ * @return relative file path as String
*/
public String makeURL(int inLayerNum, int inZoom, int inX, int inY)
{
// Check if the base url has a [1234], if so replace at random
- StringBuffer url = new StringBuffer();
- url.append(pickServerUrl(_baseUrls[inLayerNum]));
+ String baseUrl = pickServerUrl(_baseUrls[inLayerNum]);
+ return makeUrl(baseUrl, inLayerNum, inZoom, inX, inY);
+ }
+
+ public String makeUrl(String baseUrl, int inLayerNum, int inZoom, int inX, int inY)
+ {
+ // If the base URL has {x}/{y} placeholders, use them
+ if (baseUrl.contains("{x}")) {
+ baseUrl = baseUrl.replace("{z}", Integer.toString(inZoom))
+ .replace("{x}", Integer.toString(inX))
+ .replace("{y}", Integer.toString(inY));
+ return baseUrl;
+ }
+
+ // Else simply append the tile indices and file extension
+ StringBuffer url = new StringBuffer(baseUrl);
url.append(inZoom).append('/').append(inX).append('/').append(inY);
url.append('.').append(getFileExtension(inLayerNum));
if (_apiKey != null)
return url.toString();
}
+ /**
+ * Make a relative file path from the base directory including site name
+ * @param inLayerNum layer number
+ * @param inZoom zoom level
+ * @param inX x coordinate
+ * @param inY y coordinate
+ * @return relative file path as String
+ */
+ public String makeFilePath(int inLayerNum, int inZoom, int inX, int inY)
+ {
+ String siteName = getSiteName(inLayerNum);
+ String filePath = makeUrl(siteName, inLayerNum, inZoom, inX, inY);
+ int indexParam = filePath.indexOf("?");
+ if (indexParam > 0)
+ {
+ filePath = filePath.substring(0, indexParam);
+ }
+ return filePath;
+ }
+
/**
* @return maximum zoom level
*/
function.deletebydate=Delete points by date
function.addtimeoffset=Add time offset
function.addaltitudeoffset=Add altitude offset
+function.removealtitudes=Remove altitudes
function.findwaypoint=Find waypoint
function.rearrangewaypoints=Rearrange waypoints
function.convertnamestotimes=Convert waypoint names to times
confirm.reverserange=Range reversed
confirm.addtimeoffset=Time offset added
confirm.addaltitudeoffset=Altitude offset added
+confirm.removealtitudes=Altitudes removed
confirm.rearrangewaypoints=Waypoints rearranged
confirm.rearrangephotos=Photos rearranged
confirm.splitsegments=%d segment splits were made
undo.sewsegments=sew track segments
undo.addtimeoffset=add time offset
undo.addaltitudeoffset=add altitude offset
+undo.removealtitudes=remove altitudes
undo.rearrangewaypoints=rearrange waypoints
undo.cutandmove=move section
undo.connect=connect
--- /dev/null
+package tim.prune.undo;
+
+import tim.prune.I18nManager;
+import tim.prune.UpdateMessageBroker;
+import tim.prune.data.Altitude;
+import tim.prune.data.DataPoint;
+import tim.prune.data.TrackInfo;
+
+/**
+ * Undo removing (ie: restore the original) altitude from points
+ */
+public class UndoRemoveAltitudes implements UndoOperation
+{
+ /** Start index of section */
+ private int _startIndex;
+ /** altitude values before operation */
+ private Altitude[] _altitudes;
+
+
+ /**
+ * Constructor
+ * @param inTrackInfo track info object
+ */
+ public UndoRemoveAltitudes(TrackInfo inTrackInfo, int inStart, int inEnd)
+ {
+ _startIndex = inStart;
+ final int numPoints = inEnd - inStart + 1;
+ // Make array of cloned altitude objects
+ _altitudes = new Altitude[numPoints];
+ for (int i=0; i<numPoints; i++) {
+ Altitude a = inTrackInfo.getTrack().getPoint(_startIndex+i).getAltitude();
+ if (a != null && a.isValid()) {
+ _altitudes[i] = a.clone();
+ }
+ }
+ }
+
+
+ /**
+ * @return description of operation including number of points adjusted
+ */
+ public String getDescription()
+ {
+ return I18nManager.getText("undo.removealtitudes") + " (" + (_altitudes.length) + ")";
+ }
+
+
+ /**
+ * Perform the undo operation on the given Track
+ * @param inTrackInfo TrackInfo object on which to perform the operation
+ */
+ public void performUndo(TrackInfo inTrackInfo) throws UndoException
+ {
+ // Perform the inverse operation
+ final int numPoints = _altitudes.length;
+ for (int i=0; i<numPoints; i++)
+ {
+ DataPoint point = inTrackInfo.getTrack().getPoint(i+_startIndex);
+ point.resetAltitude(_altitudes[i]);
+ }
+ _altitudes = null;
+ inTrackInfo.getSelection().markInvalid();
+ UpdateMessageBroker.informSubscribers();
+ }
+}