]> gitweb.fperrin.net Git - GpsPrune.git/commitdiff
Version 16.3, July 2014
authoractivityworkshop <mail@activityworkshop.net>
Sun, 15 Feb 2015 16:08:22 +0000 (17:08 +0100)
committeractivityworkshop <mail@activityworkshop.net>
Sun, 15 Feb 2015 16:08:22 +0000 (17:08 +0100)
52 files changed:
tim/prune/App.java
tim/prune/DataStatus.java [new file with mode: 0644]
tim/prune/GpsPrune.java
tim/prune/config/Config.java
tim/prune/function/AboutScreen.java
tim/prune/function/AddMapSourceDialog.java
tim/prune/function/PhotoComparer.java
tim/prune/function/ShowThreeDFunction.java
tim/prune/function/srtm/DownloadSrtmFunction.java
tim/prune/function/weather/GetWeatherForecastFunction.java
tim/prune/function/weather/WeatherResults.java
tim/prune/function/weather/WeatherTableModel.java
tim/prune/gui/DisplayUtils.java
tim/prune/gui/TerrainDefinitionPanel.java
tim/prune/gui/images/add_photo_icon.png [changed mode: 0644->0755]
tim/prune/gui/images/add_textfile_icon.png [changed mode: 0644->0755]
tim/prune/gui/map/CloudmadeMapSource.java [deleted file]
tim/prune/gui/map/MapSourceLibrary.java
tim/prune/lang/prune-texts_cz.properties
tim/prune/lang/prune-texts_de.properties
tim/prune/lang/prune-texts_de_CH.properties
tim/prune/lang/prune-texts_en.properties
tim/prune/lang/prune-texts_en_US.properties
tim/prune/lang/prune-texts_es.properties
tim/prune/lang/prune-texts_fr.properties
tim/prune/lang/prune-texts_hu.properties
tim/prune/lang/prune-texts_it.properties
tim/prune/lang/prune-texts_ja.properties
tim/prune/lang/prune-texts_ko.properties
tim/prune/lang/prune-texts_nl.properties
tim/prune/lang/prune-texts_pl.properties
tim/prune/lang/prune-texts_pt.properties
tim/prune/lang/prune-texts_ru.properties
tim/prune/lang/prune-texts_sv.properties
tim/prune/lang/prune-texts_tr.properties
tim/prune/lang/prune-texts_zh.properties
tim/prune/load/BabelFileFormats.java
tim/prune/load/BabelLoadFromFile.java
tim/prune/readme.txt
tim/prune/save/GpsSaver.java
tim/prune/save/GpxExporter.java
tim/prune/save/PovExporter.java
tim/prune/save/xml/ByteBuffer.java [new file with mode: 0644]
tim/prune/save/xml/GpxCacher.java
tim/prune/save/xml/GpxSlicer.java
tim/prune/save/xml/XmlUtils.java
tim/prune/threedee/Java3DWindow.java
tim/prune/threedee/TerrainCache.java [new file with mode: 0644]
tim/prune/threedee/TerrainDefinition.java
tim/prune/threedee/TerrainHelper.java
tim/prune/threedee/ThreeDWindow.java
tim/prune/undo/UndoStack.java [new file with mode: 0644]

index 71bd354172ee3df66957c75b6faf1a8c08369db2..e57dcf6d5d15364fd6c5ede5f509d28728531404 100644 (file)
@@ -60,7 +60,7 @@ public class App
        private FileLoader _fileLoader = null;
        private JpegLoader _jpegLoader = null;
        private FileSaver _fileSaver = null;
        private FileLoader _fileLoader = null;
        private JpegLoader _jpegLoader = null;
        private FileSaver _fileSaver = null;
-       private Stack<UndoOperation> _undoStack = null;
+       private UndoStack _undoStack = null;
        private boolean _mangleTimestampsConfirmed = false;
        private Viewport _viewport = null;
        private ArrayList<File> _dataFiles = null;
        private boolean _mangleTimestampsConfirmed = false;
        private Viewport _viewport = null;
        private ArrayList<File> _dataFiles = null;
@@ -79,7 +79,7 @@ public class App
        public App(JFrame inFrame)
        {
                _frame = inFrame;
        public App(JFrame inFrame)
        {
                _frame = inFrame;
-               _undoStack = new Stack<UndoOperation>();
+               _undoStack = new UndoStack();
                _track = new Track();
                _trackInfo = new TrackInfo(_track);
                FunctionLibrary.initialise(this);
                _track = new Track();
                _trackInfo = new TrackInfo(_track);
                FunctionLibrary.initialise(this);
@@ -911,6 +911,12 @@ public class App
                UpdateMessageBroker.informSubscribers();
        }
 
                UpdateMessageBroker.informSubscribers();
        }
 
+       /**
+        * @return the current data status, used for later comparison
+        */
+       public DataStatus getCurrentDataStatus() {
+               return new DataStatus(_undoStack.size(), _undoStack.getNumTimesDeleted());
+       }
 
        /**
         * Show a map url in an external browser
 
        /**
         * Show a map url in an external browser
diff --git a/tim/prune/DataStatus.java b/tim/prune/DataStatus.java
new file mode 100644 (file)
index 0000000..cacb288
--- /dev/null
@@ -0,0 +1,34 @@
+package tim.prune;
+
+/**
+ * Class to remember the current status of the data,
+ * and make it possible to see whether the data has
+ * changed in any way since the DataStatus was requested
+ */
+public class DataStatus
+{
+       private int _undoSize = 0;
+       private int _deleteCount = 0;
+
+       /**
+        * Constructor
+        * @param inUndoSize current size of undo stack
+        * @param inDeleteCount number of times undo stack has been deleted
+        */
+       public DataStatus(int inUndoSize, int inDeleteCount)
+       {
+               _undoSize = inUndoSize;
+               _deleteCount = inDeleteCount;
+       }
+
+       /**
+        * Has the data changed compared to the previous status?
+        * @param inPreviousStatus previous status obtained from App
+        * @return true if the status is now different
+        */
+       public boolean hasDataChanged(DataStatus inPreviousStatus)
+       {
+               return _undoSize != inPreviousStatus._undoSize
+                       || _deleteCount != inPreviousStatus._deleteCount;
+       }
+}
index 0503ddaaf12d9365230e55853f29c0e285dd16f7..dd907653c10eec569035e6074d6c90df3565862f 100644 (file)
@@ -35,9 +35,9 @@ import tim.prune.gui.profile.ProfileChart;
 public class GpsPrune
 {
        /** Version number of application, used in about screen and for version check */
 public class GpsPrune
 {
        /** Version number of application, used in about screen and for version check */
-       public static final String VERSION_NUMBER = "16";
+       public static final String VERSION_NUMBER = "16.3";
        /** Build number, just used for about screen */
        /** Build number, just used for about screen */
-       public static final String BUILD_NUMBER = "301";
+       public static final String BUILD_NUMBER = "303c";
        /** Static reference to App object */
        private static App APP = null;
 
        /** Static reference to App object */
        private static App APP = null;
 
index 655847cf338cf9b4900cb426c850f1a8248d8681..35f5a311cea8cf8d19cfdb5b825c620e38f48abb 100644 (file)
@@ -45,6 +45,8 @@ public abstract class Config
        public static final String KEY_GPS_FORMAT = "prune.gpsformat";
        /** Key for GPSBabel filter string */
        public static final String KEY_GPSBABEL_FILTER = "prune.gpsbabelfilter";
        public static final String KEY_GPS_FORMAT = "prune.gpsformat";
        /** Key for GPSBabel filter string */
        public static final String KEY_GPSBABEL_FILTER = "prune.gpsbabelfilter";
+       /** Key for GPSBabel import file format */
+       public static final String KEY_IMPORT_FILE_FORMAT = "prune.lastimportfileformat";
        /** Key for Povray font */
        public static final String KEY_POVRAY_FONT = "prune.povrayfont";
        /** Key for the selected unit set */
        /** Key for Povray font */
        public static final String KEY_POVRAY_FONT = "prune.povrayfont";
        /** Key for the selected unit set */
@@ -169,6 +171,7 @@ public abstract class Config
                props.put(KEY_EXIFTOOL_PATH, "exiftool");
                props.put(KEY_GNUPLOT_PATH, "gnuplot");
                props.put(KEY_GPSBABEL_PATH, "gpsbabel");
                props.put(KEY_EXIFTOOL_PATH, "exiftool");
                props.put(KEY_GNUPLOT_PATH, "gnuplot");
                props.put(KEY_GPSBABEL_PATH, "gpsbabel");
+               props.put(KEY_IMPORT_FILE_FORMAT, "-1"); // no file format selected
                props.put(KEY_KMZ_IMAGE_SIZE, "240");
                props.put(KEY_AUTOSAVE_SETTINGS, "0"); // autosave false by default
                props.put(KEY_UNITSET_KEY, "unitset.kilometres"); // metric by default
                props.put(KEY_KMZ_IMAGE_SIZE, "240");
                props.put(KEY_AUTOSAVE_SETTINGS, "0"); // autosave false by default
                props.put(KEY_UNITSET_KEY, "unitset.kilometres"); // metric by default
index 70a9eb35ca6109e1af3abdcd0ae10b798f817e79..5a463a3d61bff35efa3233168728cb409ea28ffc 100644 (file)
@@ -99,7 +99,7 @@ public class AboutScreen extends GenericFunction
                descBuffer.append("<p>").append(I18nManager.getText("dialog.about.languages")).append(" : ")
                        .append("\u010de\u0161tina, deutsch, english, espa\u00F1ol, fran\u00E7ais, italiano, magyar,<br>" +
                                " nederlands, polski, portugu\u00EAs, \u0440\u0443\u0441\u0441\u043a\u0438\u0439 (russian), \u4e2d\u6587 (chinese), \u65E5\u672C\u8A9E (japanese),<br>" +
                descBuffer.append("<p>").append(I18nManager.getText("dialog.about.languages")).append(" : ")
                        .append("\u010de\u0161tina, deutsch, english, espa\u00F1ol, fran\u00E7ais, italiano, magyar,<br>" +
                                " nederlands, polski, portugu\u00EAs, \u0440\u0443\u0441\u0441\u043a\u0438\u0439 (russian), \u4e2d\u6587 (chinese), \u65E5\u672C\u8A9E (japanese),<br>" +
-                               " \uD55C\uAD6D\uC5B4/\uC870\uC120\uB9D0 (korean), schwiizerd\u00FC\u00FCtsch, t\u00FCrk\u00E7e, afrikaans, rom\u00E2n\u0103</p>");
+                               " \uD55C\uAD6D\uC5B4/\uC870\uC120\uB9D0 (korean), schwiizerd\u00FC\u00FCtsch, t\u00FCrk\u00E7e, afrikaans, rom\u00E2n\u0103, ukrainian</p>");
                descBuffer.append("<p>").append(I18nManager.getText("dialog.about.translatedby")).append("</p>");
                JEditorPane descPane = new JEditorPane("text/html", descBuffer.toString());
                descPane.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
                descBuffer.append("<p>").append(I18nManager.getText("dialog.about.translatedby")).append("</p>");
                JEditorPane descPane = new JEditorPane("text/html", descBuffer.toString());
                descPane.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
index bcc8b7064bed60cb5f81b5672e560f8600f5c1a8..9207ac5655a82b2464a18daf2d8119cb001225f8 100644 (file)
@@ -1,12 +1,10 @@
 package tim.prune.function;
 
 import java.awt.BorderLayout;
 package tim.prune.function;
 
 import java.awt.BorderLayout;
-import java.awt.CardLayout;
 import java.awt.Component;
 import java.awt.FlowLayout;
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
 import java.awt.Component;
 import java.awt.FlowLayout;
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
-import java.awt.GridLayout;
 import java.awt.Insets;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.Insets;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
@@ -24,7 +22,6 @@ import javax.swing.JRadioButton;
 import javax.swing.JTextField;
 
 import tim.prune.I18nManager;
 import javax.swing.JTextField;
 
 import tim.prune.I18nManager;
-import tim.prune.gui.map.CloudmadeMapSource;
 import tim.prune.gui.map.MapSource;
 import tim.prune.gui.map.MapSourceLibrary;
 import tim.prune.gui.map.OsmMapSource;
 import tim.prune.gui.map.MapSource;
 import tim.prune.gui.map.MapSourceLibrary;
 import tim.prune.gui.map.OsmMapSource;
@@ -36,18 +33,12 @@ public class AddMapSourceDialog
 {
        private SetMapBgFunction _parent = null;
        private JDialog _addDialog = null;
 {
        private SetMapBgFunction _parent = null;
        private JDialog _addDialog = null;
-       private JRadioButton[] _sourceTypeRadios = null;
-       private JPanel _cards = null;
        private MapSource _originalSource = null;
        // controls for osm panel
        private JTextField _oNameField = null;
        private JTextField _baseUrlField = null, _topUrlField = null;
        private JRadioButton[] _baseTypeRadios = null, _topTypeRadios = null;
        private JComboBox<Integer> _oZoomCombo = null;
        private MapSource _originalSource = null;
        // controls for osm panel
        private JTextField _oNameField = null;
        private JTextField _baseUrlField = null, _topUrlField = null;
        private JRadioButton[] _baseTypeRadios = null, _topTypeRadios = null;
        private JComboBox<Integer> _oZoomCombo = null;
-       // controls for cloudmade panel
-       private JTextField _cNameField = null;
-       private JTextField _cStyleField = null;
-       private JComboBox<Integer> _cZoomCombo = null;
        private JButton _okButton = null;
 
        /** array of file types */
        private JButton _okButton = null;
 
        /** array of file types */
@@ -76,31 +67,9 @@ public class AddMapSourceDialog
        {
                JPanel dialogPanel = new JPanel();
                dialogPanel.setLayout(new BorderLayout());
        {
                JPanel dialogPanel = new JPanel();
                dialogPanel.setLayout(new BorderLayout());
-               // Top panel with two radio buttons to select source type
-               JPanel radioPanel = new JPanel();
-               ButtonGroup radioGroup = new ButtonGroup();
-               radioPanel.setLayout(new GridLayout(1, 0));
-               _sourceTypeRadios = new JRadioButton[2];
-               _sourceTypeRadios[0] = new JRadioButton("Openstreetmap");
-               radioGroup.add(_sourceTypeRadios[0]);
-               radioPanel.add(_sourceTypeRadios[0]);
-               _sourceTypeRadios[1] = new JRadioButton("Cloudmade");
-               radioGroup.add(_sourceTypeRadios[1]);
-               radioPanel.add(_sourceTypeRadios[1]);
-               _sourceTypeRadios[0].setSelected(true);
-               // listener for clicks on type radios
-               ActionListener typeListener = new ActionListener() {
-                       public void actionPerformed(ActionEvent arg0) {
-                               onRadioClicked();
-                       }
-               };
-               _sourceTypeRadios[0].addActionListener(typeListener);
-               _sourceTypeRadios[1].addActionListener(typeListener);
-               radioPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
-               dialogPanel.add(radioPanel, BorderLayout.NORTH);
+               // Top panel with spacer
+               dialogPanel.add(new JLabel(" "), BorderLayout.NORTH);
 
 
-               _cards = new JPanel();
-               _cards.setLayout(new CardLayout());
                // listener
                KeyAdapter keyListener = new KeyAdapter() {
                        public void keyReleased(KeyEvent e) {
                // listener
                KeyAdapter keyListener = new KeyAdapter() {
                        public void keyReleased(KeyEvent e) {
@@ -149,7 +118,7 @@ public class AddMapSourceDialog
                c.gridx = 1; c.weightx = 1.0;
                gbPanel.add(_baseUrlField, c);
                _baseTypeRadios = new JRadioButton[3];
                c.gridx = 1; c.weightx = 1.0;
                gbPanel.add(_baseUrlField, c);
                _baseTypeRadios = new JRadioButton[3];
-               radioGroup = new ButtonGroup();
+               ButtonGroup radioGroup = new ButtonGroup();
                for (int i=0; i<3; i++)
                {
                        _baseTypeRadios[i] = new JRadioButton(FILE_TYPES[i]);
                for (int i=0; i<3; i++)
                {
                        _baseTypeRadios[i] = new JRadioButton(FILE_TYPES[i]);
@@ -190,35 +159,11 @@ public class AddMapSourceDialog
                c.gridx = 1;
                gbPanel.add(_oZoomCombo, c);
                osmPanel.add(gbPanel, BorderLayout.NORTH);
                c.gridx = 1;
                gbPanel.add(_oZoomCombo, c);
                osmPanel.add(gbPanel, BorderLayout.NORTH);
-               _cards.add(osmPanel, "card1");
 
 
-               // Panel for cloudmade source
-               JPanel cloudPanel = new JPanel();
-               cloudPanel.setBorder(BorderFactory.createEmptyBorder(6, 3, 4, 3));
-               // Use a gridlayout inside a borderlayout to avoid stretching
-               cloudPanel.setLayout(new BorderLayout());
-               JPanel cloudGridPanel = new JPanel();
-               cloudGridPanel.setLayout(new GridLayout(0, 2, 5, 5));
-               cloudGridPanel.add(new JLabel(I18nManager.getText("dialog.addmapsource.sourcename")));
-               _cNameField = new JTextField(18);
-               _cNameField.addKeyListener(keyListener);
-               cloudGridPanel.add(_cNameField);
-               cloudGridPanel.add(new JLabel(I18nManager.getText("dialog.addmapsource.cloudstyle")));
-               _cStyleField = new JTextField(18);
-               _cStyleField.addKeyListener(keyListener);
-               cloudGridPanel.add(_cStyleField);
-               cloudGridPanel.add(new JLabel(I18nManager.getText("dialog.addmapsource.maxzoom")));
-               _cZoomCombo = new JComboBox<Integer>();
-               for (int i=10; i<=20; i++) {
-                       _cZoomCombo.addItem(i);
-               }
-               cloudGridPanel.add(_cZoomCombo);
-               cloudPanel.add(cloudGridPanel, BorderLayout.NORTH);
-               _cards.add(cloudPanel, "card2");
                // cards
                JPanel holderPanel = new JPanel();
                holderPanel.setLayout(new BorderLayout());
                // cards
                JPanel holderPanel = new JPanel();
                holderPanel.setLayout(new BorderLayout());
-               holderPanel.add(_cards, BorderLayout.NORTH);
+               holderPanel.add(osmPanel, BorderLayout.NORTH);
                dialogPanel.add(holderPanel, BorderLayout.CENTER);
 
                // button panel at bottom
                dialogPanel.add(holderPanel, BorderLayout.CENTER);
 
                // button panel at bottom
@@ -267,13 +212,7 @@ public class AddMapSourceDialog
                _topUrlField.setText("");
                _topTypeRadios[0].setSelected(true);
                _oZoomCombo.setSelectedIndex(8);
                _topUrlField.setText("");
                _topTypeRadios[0].setSelected(true);
                _oZoomCombo.setSelectedIndex(8);
-               _cNameField.setText("");
-               _cStyleField.setText("");
-               _cZoomCombo.setSelectedIndex(8);
                _okButton.setEnabled(false);
                _okButton.setEnabled(false);
-               for (int i=0; i<2; i++) {
-                       _sourceTypeRadios[i].setEnabled(true);
-               }
                _addDialog.setVisible(true);
        }
 
                _addDialog.setVisible(true);
        }
 
@@ -287,67 +226,32 @@ public class AddMapSourceDialog
                        clearAllFields();
                        return;
                }
                        clearAllFields();
                        return;
                }
-               boolean sourceFound = false;
-               // See if it's a cloudmade source
+
+               // See if it's an osm source
                try
                {
                try
                {
-                       CloudmadeMapSource cloudSource = (CloudmadeMapSource) _originalSource;
-                       sourceFound = true;
-                       _cNameField.setText(cloudSource.getName());
-                       _cStyleField.setText(cloudSource.getStyle());
-                       _cZoomCombo.setSelectedIndex(getZoomIndex(cloudSource.getMaxZoomLevel()));
-                       _sourceTypeRadios[1].setSelected(true);
+                       OsmMapSource osmSource = (OsmMapSource) _originalSource;
+                       _oNameField.setText(osmSource.getName());
+                       _baseUrlField.setText(osmSource.getBaseUrl(0));
+                       int baseType = getBaseType(osmSource.getFileExtension(0));
+                       _baseTypeRadios[baseType].setSelected(true);
+                       _topUrlField.setText(osmSource.getNumLayers()==0?"":osmSource.getBaseUrl(1));
+                       int topType = getBaseType(osmSource.getFileExtension(1));
+                       _topTypeRadios[topType].setSelected(true);
+                       _oZoomCombo.setSelectedIndex(getZoomIndex(osmSource.getMaxZoomLevel()));
                }
                catch (ClassCastException cce) {} // ignore, sourceFound flag stays false
 
                }
                catch (ClassCastException cce) {} // ignore, sourceFound flag stays false
 
-               // See if it's an osm source
-               if (!sourceFound)
-               {
-                       try
-                       {
-                               OsmMapSource osmSource = (OsmMapSource) _originalSource;
-                               sourceFound = true;
-                               _oNameField.setText(osmSource.getName());
-                               _baseUrlField.setText(osmSource.getBaseUrl(0));
-                               int baseType = getBaseType(osmSource.getFileExtension(0));
-                               _baseTypeRadios[baseType].setSelected(true);
-                               _topUrlField.setText(osmSource.getNumLayers()==0?"":osmSource.getBaseUrl(1));
-                               int topType = getBaseType(osmSource.getFileExtension(1));
-                               _topTypeRadios[topType].setSelected(true);
-                               _oZoomCombo.setSelectedIndex(getZoomIndex(osmSource.getMaxZoomLevel()));
-                               _sourceTypeRadios[0].setSelected(true);
-                       }
-                       catch (ClassCastException cce) {} // ignore, sourceFound flag stays false
-               }
-               for (int i=0; i<2; i++) {
-                       _sourceTypeRadios[i].setEnabled(false);
-               }
-               onRadioClicked();
                _okButton.setEnabled(false);
                _addDialog.setVisible(true);
        }
 
                _okButton.setEnabled(false);
                _addDialog.setVisible(true);
        }
 
-
-       /**
-        * React to one of the type radio buttons being clicked
-        */
-       private void onRadioClicked()
-       {
-               CardLayout cl = (CardLayout) _cards.getLayout();
-               if (_sourceTypeRadios[0].isSelected()) {cl.first(_cards);}
-               else {cl.last(_cards);}
-               enableOK();
-       }
-
        /**
         * Check the currently entered details and enable the OK button if it looks OK
         */
        private void enableOK()
        {
        /**
         * Check the currently entered details and enable the OK button if it looks OK
         */
        private void enableOK()
        {
-               boolean ok = false;
-               if (_sourceTypeRadios[0].isSelected()) {ok = isOsmPanelOk();}
-               if (_sourceTypeRadios[1].isSelected()) {ok = isCloudPanelOk();}
-               _okButton.setEnabled(ok);
+               _okButton.setEnabled(isOsmPanelOk());
        }
 
        /**
        }
 
        /**
@@ -370,21 +274,6 @@ public class AddMapSourceDialog
                return (ok && (baseUrl != null || topUrl != null));
        }
 
                return (ok && (baseUrl != null || topUrl != null));
        }
 
-       /**
-        * Check the cloudmade panel if all details are complete
-        * @return true if details look ok
-        */
-       private boolean isCloudPanelOk()
-       {
-               boolean ok = _cNameField.getText().trim().length() > 1;
-               int styleNum = 0;
-               try {
-                       styleNum = Integer.parseInt(_cStyleField.getText());
-               }
-               catch (NumberFormatException nfe) {}
-               return (ok && styleNum > 0);
-       }
-
        /**
         * Finish by adding the requested source and refreshing the parent
         */
        /**
         * Finish by adding the requested source and refreshing the parent
         */
@@ -392,7 +281,8 @@ public class AddMapSourceDialog
        {
                MapSource newSource = null;
                String origName = (_originalSource == null ? null : _originalSource.getName());
        {
                MapSource newSource = null;
                String origName = (_originalSource == null ? null : _originalSource.getName());
-               if (_sourceTypeRadios[0].isSelected())
+
+               if (isOsmPanelOk())
                {
                        // Openstreetmap source
                        String sourceName = getValidSourcename(_oNameField.getText(), origName);
                {
                        // Openstreetmap source
                        String sourceName = getValidSourcename(_oNameField.getText(), origName);
@@ -402,12 +292,7 @@ public class AddMapSourceDialog
                        String ext2 = getFileExtension(_topTypeRadios);
                        newSource = new OsmMapSource(sourceName, url1, ext1, url2, ext2, _oZoomCombo.getSelectedIndex()+10);
                }
                        String ext2 = getFileExtension(_topTypeRadios);
                        newSource = new OsmMapSource(sourceName, url1, ext1, url2, ext2, _oZoomCombo.getSelectedIndex()+10);
                }
-               else if (_sourceTypeRadios[1].isSelected())
-               {
-                       String sourceName = getValidSourcename(_cNameField.getText(), origName);
-                       newSource = new CloudmadeMapSource(sourceName, _cStyleField.getText(),
-                               _cZoomCombo.getSelectedIndex()+10);
-               }
+
                // Add new source if ok
                if (newSource != null)
                {
                // Add new source if ok
                if (newSource != null)
                {
index 86252d199bfd7d804c744f9a700ad4d6997a6d67..b15d57c981653e884266124fd82ace0058cd1035 100644 (file)
@@ -48,7 +48,7 @@ public class PhotoComparer implements Comparator<DataPoint>
                if (result == 0) {
                        result = compareSizes(inP1, inP2);
                }
                if (result == 0) {
                        result = compareSizes(inP1, inP2);
                }
-               return 0;
+               return result;
        }
 
        /**
        }
 
        /**
index bbe771988fd640ee673a81b28f8d04c16cc95191..40c4e5af9f2a6e2b0057c81fce60ebb29ec6ce51 100644 (file)
@@ -57,7 +57,7 @@ public class ShowThreeDFunction extends GenericFunction
        }
 
        /**
        }
 
        /**
-        * Show the help screen
+        * Begin the function
         */
        public void begin()
        {
         */
        public void begin()
        {
@@ -169,6 +169,7 @@ public class ShowThreeDFunction extends GenericFunction
                                // Also pass the base image parameters from input dialog
                                window.setBaseImageParameters(_baseImagePanel.getImageDefinition());
                                window.setTerrainParameters(new TerrainDefinition(_terrainPanel.getUseTerrain(), _terrainPanel.getGridSize()));
                                // Also pass the base image parameters from input dialog
                                window.setBaseImageParameters(_baseImagePanel.getImageDefinition());
                                window.setTerrainParameters(new TerrainDefinition(_terrainPanel.getUseTerrain(), _terrainPanel.getGridSize()));
+                               window.setDataStatus(_app.getCurrentDataStatus());
                                window.show();
                        }
                        catch (ThreeDException e)
                                window.show();
                        }
                        catch (ThreeDException e)
index 8517cd0e88e083aa78d763e38754219e04b1e590..d0d92bb152062a7515a67410746643397a715173 100644 (file)
@@ -175,7 +175,12 @@ public class DownloadSrtmFunction extends GenericFunction implements Runnable
                if (errorMessage != null) {
                        _app.showErrorMessageNoLookup(getNameKey(), errorMessage);
                }
                if (errorMessage != null) {
                        _app.showErrorMessageNoLookup(getNameKey(), errorMessage);
                }
-               else if (numDownloaded > 0)
+               else if (numDownloaded == 1)
+               {
+                       JOptionPane.showMessageDialog(_parentFrame, I18nManager.getTextWithNumber("confirm.downloadsrtm.1", numDownloaded),
+                               I18nManager.getText(getNameKey()), JOptionPane.INFORMATION_MESSAGE);
+               }
+               else if (numDownloaded > 1)
                {
                        JOptionPane.showMessageDialog(_parentFrame, I18nManager.getTextWithNumber("confirm.downloadsrtm", numDownloaded),
                                I18nManager.getText(getNameKey()), JOptionPane.INFORMATION_MESSAGE);
                {
                        JOptionPane.showMessageDialog(_parentFrame, I18nManager.getTextWithNumber("confirm.downloadsrtm", numDownloaded),
                                I18nManager.getText(getNameKey()), JOptionPane.INFORMATION_MESSAGE);
index 7b6f8c7602dcce9ea88b0e44699876b262b32eb6..970d022f67032ce0e45cc9ffce7e5921abb77486 100644 (file)
@@ -73,6 +73,8 @@ public class GetWeatherForecastFunction extends GenericFunction implements Runna
 
        /** True to just simulate the calls and read files instead, false to call real API */
        private static final boolean SIMULATE_WITH_FILES = false;
 
        /** True to just simulate the calls and read files instead, false to call real API */
        private static final boolean SIMULATE_WITH_FILES = false;
+       /** Unique API key for GpsPrune */
+       private static final String OPENWEATHERMAP_API_KEY = "d1c5d792362f5a5c2eacf70a3b72ecd6";
 
 
        /**
 
 
        /**
@@ -365,7 +367,8 @@ public class GetWeatherForecastFunction extends GenericFunction implements Runna
                        + (_locationId == null ? ("lat=" + NumberUtils.formatNumberUk(lat, 5) + "&lon=" + NumberUtils.formatNumberUk(lon, 5))
                                : ("id=" + _locationId))
                        + "&lang=" + I18nManager.getText("openweathermap.lang")
                        + (_locationId == null ? ("lat=" + NumberUtils.formatNumberUk(lat, 5) + "&lon=" + NumberUtils.formatNumberUk(lon, 5))
                                : ("id=" + _locationId))
                        + "&lang=" + I18nManager.getText("openweathermap.lang")
-                       + "&mode=xml&units=" + (inUseCelsius ? "metric" : "imperial");
+                       + "&mode=xml&units=" + (inUseCelsius ? "metric" : "imperial")
+                       + "&APPID=" + OPENWEATHERMAP_API_KEY;
                // System.out.println(urlString);
 
                // Parse the returned XML with a special handler
                // System.out.println(urlString);
 
                // Parse the returned XML with a special handler
@@ -431,7 +434,8 @@ public class GetWeatherForecastFunction extends GenericFunction implements Runna
                final String forecastCount = inDaily ? "8" : "3";
                final String urlString = "http://api.openweathermap.org/data/2.5/forecast"
                        + (inDaily ? "/daily" : "") + "?id=" + _locationId + "&lang=" + I18nManager.getText("openweathermap.lang")
                final String forecastCount = inDaily ? "8" : "3";
                final String urlString = "http://api.openweathermap.org/data/2.5/forecast"
                        + (inDaily ? "/daily" : "") + "?id=" + _locationId + "&lang=" + I18nManager.getText("openweathermap.lang")
-                       + "&mode=xml&units=" + (inCelsius ? "metric" : "imperial") + "&cnt=" + forecastCount;
+                       + "&mode=xml&units=" + (inCelsius ? "metric" : "imperial") + "&cnt=" + forecastCount
+                       + "&APPID=" + OPENWEATHERMAP_API_KEY;
                // System.out.println(urlString);
 
                // Parse the returned XML with a special handler
                // System.out.println(urlString);
 
                // Parse the returned XML with a special handler
index 83c5ca0dfeb0828cfe9f0666d3e6768bca780cbe..10fd3635fd5474326dbc1ba6b3ba527f59cd132b 100644 (file)
@@ -1,6 +1,10 @@
 package tim.prune.function.weather;
 
 import java.util.ArrayList;
 package tim.prune.function.weather;
 
 import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.TimeZone;
+
+import tim.prune.gui.DisplayUtils;
 
 
 /**
 
 
 /**
@@ -96,8 +100,9 @@ public class WeatherResults
                if (inRiseTime != null && inRiseTime.length() == 19
                        && inSetTime != null && inSetTime.length() == 19)
                {
                if (inRiseTime != null && inRiseTime.length() == 19
                        && inSetTime != null && inSetTime.length() == 19)
                {
-                       _sunriseTime = inRiseTime.substring(11, 16);
-                       _sunsetTime  = inSetTime.substring(11, 16);
+                       // Convert from UTC to system's time zone (not necessarily target's time zone!)
+                       _sunriseTime = convertToLocalTimezone(inRiseTime.substring(11, 16));
+                       _sunsetTime  = convertToLocalTimezone(inSetTime.substring(11, 16));
                }
        }
 
                }
        }
 
@@ -130,4 +135,32 @@ public class WeatherResults
        {
                return _updateTime;
        }
        {
                return _updateTime;
        }
+
+       /**
+        * Convert the given UTC time (HH:MM) into current timezone of computer
+        * @param inTimeString sunrise/sunset time in UTC (HH:MM)
+        * @return time in this timezone (HH:MM)
+        */
+       private static String convertToLocalTimezone(String inTimeString)
+       {
+               if (inTimeString != null && inTimeString.length() == 5)
+               {
+                       try
+                       {
+                               final int hour = Integer.parseInt(inTimeString.substring(0, 2));
+                               final int min  = Integer.parseInt(inTimeString.substring(3));
+                               Calendar utcCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+                               utcCal.set(Calendar.HOUR_OF_DAY, hour);
+                               utcCal.set(Calendar.MINUTE, min);
+                               // Make a second calendar in the current time zone and apply values
+                               Calendar currCal = Calendar.getInstance();
+                               currCal.setTimeInMillis(utcCal.getTimeInMillis());
+                               return DisplayUtils.makeTimeString(currCal.get(Calendar.HOUR_OF_DAY),
+                                       currCal.get(Calendar.MINUTE));
+                       }
+                       catch (NumberFormatException e) {} // ignore, just drop through
+               }
+               // Couldn't be parsed / converted
+               return inTimeString;
+       }
 }
 }
index 274490e12256bfade9b79ceb7ce06f689cb1ccb4..35444b6dc9387786e5b870cc34f0c4f9da8000ea 100644 (file)
@@ -84,13 +84,12 @@ public class WeatherTableModel extends AbstractTableModel
                                        return buildDisplayString(null, I18nManager.getText("dialog.weather.day." + dayDesc));
                                }
                                case ROW_DESC: return buildDisplayString(null, forecast.getDescription());
                                        return buildDisplayString(null, I18nManager.getText("dialog.weather.day." + dayDesc));
                                }
                                case ROW_DESC: return buildDisplayString(null, forecast.getDescription());
-                               case ROW_WIND: return buildDisplayString("Wind", forecast.getWindDescription());
+                               case ROW_WIND: return buildDisplayString(I18nManager.getText("dialog.weather.wind"), forecast.getWindDescription());
                                case ROW_ICON: return forecast.getImageName();
                                case ROW_ICON: return forecast.getImageName();
-                               case ROW_TEMP: return buildDisplayString("Temp", forecast.getTemps()
+                               case ROW_TEMP: return buildDisplayString(I18nManager.getText("dialog.weather.temp"), forecast.getTemps()
                                        + (_results.isCelsius() ? UNITS_DEGC : UNITS_DEGF));
                                        + (_results.isCelsius() ? UNITS_DEGC : UNITS_DEGF));
-                               case ROW_HUMID: return buildDisplayString("Humidity", forecast.getHumidity());
+                               case ROW_HUMID: return buildDisplayString(I18nManager.getText("dialog.weather.humidity"), forecast.getHumidity());
                        }
                        }
-                       // TODO: Use language-specific texts for wind, temp and humidity
                }
                return "";
        }
                }
                return "";
        }
index 49ca3870b6304ccc3bc2c40f56b18d2b3685a6fe..25640d8e5072bfc2e70acfc3e26c7de208a494e3 100644 (file)
@@ -70,4 +70,24 @@ public abstract class DisplayUtils
                FORMAT_FLEX.setMinimumFractionDigits(numDigits);
                return FORMAT_FLEX.format(inVal);
        }
                FORMAT_FLEX.setMinimumFractionDigits(numDigits);
                return FORMAT_FLEX.format(inVal);
        }
+
+       /**
+        * Convert the given hour and minute values into a string H:MM
+        * @param inHour hour of day, 0-24
+        * @param inMinute minute, 0-59
+        * @return string, either H:MM or HH:MM
+        */
+       public static String makeTimeString(int inHour, int inMinute)
+       {
+               StringBuilder sb = new StringBuilder();
+               final int hour = (inHour >= 0 && inHour <= 24) ? inHour : 0;
+               sb.append(hour);
+
+               sb.append(':');
+
+               final int minute = (inMinute >= 0 && inMinute <= 59) ? inMinute : 0;
+               if (minute <= 9) {sb.append('0');}
+               sb.append(minute);
+               return sb.toString();
+       }
 }
 }
index 690c1aed55f81c91c1513be274c3f765dde9e308..064aa119da12452de470eeb3c9c7b3a75576e964 100644 (file)
@@ -44,7 +44,7 @@ public class TerrainDefinitionPanel extends JPanel
                JLabel label = new JLabel(I18nManager.getText("dialog.3d.terraingridsize") + ": ");
                add(label);
                _gridSizeField = new WholeNumberField(4);
                JLabel label = new JLabel(I18nManager.getText("dialog.3d.terraingridsize") + ": ");
                add(label);
                _gridSizeField = new WholeNumberField(4);
-               _gridSizeField.setValue(10);
+               _gridSizeField.setValue(50); // default grid size
                _gridSizeField.setMaximumSize(new Dimension(100, 50));
                _gridSizeField.setEnabled(false);
                add(_gridSizeField);
                _gridSizeField.setMaximumSize(new Dimension(100, 50));
                _gridSizeField.setEnabled(false);
                add(_gridSizeField);
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/tim/prune/gui/map/CloudmadeMapSource.java b/tim/prune/gui/map/CloudmadeMapSource.java
deleted file mode 100644 (file)
index 17d4efe..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-package tim.prune.gui.map;
-
-/**
- * Class to act as a source for Cloudmade maps with a given style
- */
-public class CloudmadeMapSource extends OsmMapSource
-{
-       /** Selected style number */
-       private String _style = null;
-       /** Server prefix including API-key unique to GpsPrune application */
-       private static final String SERVER_PREFIX = "[abc].tile.cloudmade.com/03d86b66f51f4a3b8c236ac06f2a2e57/";
-
-       /**
-        * Constructor
-        * @param inName name to use for map source
-        * @param inStyle style, given as integer
-        * @param inMaxZoom maximum zoom level, 18 by default
-        */
-       public CloudmadeMapSource(String inName, String inStyle, int inMaxZoom)
-       {
-               // Note: Could check style for valid integer value here
-               super(inName, SERVER_PREFIX + inStyle + "/256/", null, inMaxZoom);
-               _style = inStyle;
-       }
-
-       /**
-        * @return semicolon-separated list of all fields
-        */
-       public String getConfigString()
-       {
-               return "c:" +  getName() + ";" + _style + ";" + getMaxZoomLevel();
-       }
-
-       /**
-        * Construct a new map source from its config string
-        * @param inConfigString string from Config, separated by semicolons
-        * @return new map source, or null if not parseable
-        */
-       public static CloudmadeMapSource fromConfig(String inConfigString)
-       {
-               CloudmadeMapSource source = null;
-               if (inConfigString.startsWith("c:"))
-               {
-                       String[] items = inConfigString.substring(2).split(";");
-                       try {
-                               if (items.length == 3) {
-                                       source = new CloudmadeMapSource(items[0], items[1], Integer.parseInt(items[2]));
-                               }
-                       } catch (NumberFormatException nfe) {}
-               }
-               return source;
-       }
-
-       /**
-        * @return style as string, only required to populate edit dialog
-        */
-       public String getStyle()
-       {
-               return _style;
-       }
-}
index 5c20eacf9ba9fdc8a2da4bc4b76cf77e8f46b263..b82fd4e7a23e197a80120eb6d2b2e0c7a854f409 100644 (file)
@@ -47,7 +47,6 @@ public abstract class MapSourceLibrary
                        "http://toolserver.org/~cmarqu/hill/", 18));
                _sourceList.add(new OsmMapSource("Openseamap", "http://tile.openstreetmap.org/",
                        "http://tiles.openseamap.org/seamark/", 18));
                        "http://toolserver.org/~cmarqu/hill/", 18));
                _sourceList.add(new OsmMapSource("Openseamap", "http://tile.openstreetmap.org/",
                        "http://tiles.openseamap.org/seamark/", 18));
-               _sourceList.add(new CloudmadeMapSource("Pale Dawn", "998", 18));
        }
 
        /**
        }
 
        /**
@@ -64,7 +63,6 @@ public abstract class MapSourceLibrary
                        {
                                String sourceString = configString.substring(0, splitPos);
                                MapSource source = OsmMapSource.fromConfig(sourceString);
                        {
                                String sourceString = configString.substring(0, splitPos);
                                MapSource source = OsmMapSource.fromConfig(sourceString);
-                               if (source == null) {source = CloudmadeMapSource.fromConfig(sourceString);}
                                if (source != null) {
                                        _sourceList.add(source);
                                }
                                if (source != null) {
                                        _sourceList.add(source);
                                }
index fc6c7ff18b50c69328b6b19193d9373a323f29c7..cab34c731463e498c3b98aa9ff606c85ad7132a5 100644 (file)
@@ -358,7 +358,6 @@ dialog.addmapsource.sourcename=N\u00e1zev zdroje
 dialog.addmapsource.layer1url=URL prvn\u00ed vrstvy
 dialog.addmapsource.layer2url=Voliteln\u011b URL druh\u00e9 vrstvy
 dialog.addmapsource.maxzoom=Maxim\u00e1ln\u00ed zv\u011bt\u0161en\u00ed
 dialog.addmapsource.layer1url=URL prvn\u00ed vrstvy
 dialog.addmapsource.layer2url=Voliteln\u011b URL druh\u00e9 vrstvy
 dialog.addmapsource.maxzoom=Maxim\u00e1ln\u00ed zv\u011bt\u0161en\u00ed
-dialog.addmapsource.cloudstyle=\u010c\u00edslo stylu
 dialog.addmapsource.noname=Bez n\u00e1zvu
 dialog.gpsies.column.name=N\u00e1zev stopy
 dialog.gpsies.column.length=D\u00e9lka
 dialog.addmapsource.noname=Bez n\u00e1zvu
 dialog.gpsies.column.name=N\u00e1zev stopy
 dialog.gpsies.column.length=D\u00e9lka
@@ -601,6 +600,7 @@ confirm.rotatephoto=fotografie oto\u010dena
 confirm.running=Prob\u00edh\u00e1 ...
 confirm.lookupsrtm=Nalezeno %d v\u00fd\u0161kov\u00fdch hodnot
 confirm.downloadsrtm=Do cache bylo sta\u017eeno %d soubor\u016f
 confirm.running=Prob\u00edh\u00e1 ...
 confirm.lookupsrtm=Nalezeno %d v\u00fd\u0161kov\u00fdch hodnot
 confirm.downloadsrtm=Do cache bylo sta\u017eeno %d soubor\u016f
+confirm.downloadsrtm.1=Do cache bylo sta\u017eeno %d soubor\u016f
 confirm.downloadsrtm.none=\u017d\u00e1dn\u00fd soubor nebylo t\u0159eba stahovat, v\u0161e u\u017e je v cachi.
 confirm.deletefieldvalues=Hodnoty pole smaz\u00e1ny
 confirm.audioload=Audionahr\u00e1vky p\u0159id\u00e1ny
 confirm.downloadsrtm.none=\u017d\u00e1dn\u00fd soubor nebylo t\u0159eba stahovat, v\u0161e u\u017e je v cachi.
 confirm.deletefieldvalues=Hodnoty pole smaz\u00e1ny
 confirm.audioload=Audionahr\u00e1vky p\u0159id\u00e1ny
index 91f75ac6b3e90e321606c1ccc0fb7e8d1706b314..19b6b029fe1906183bc79c90b63a38ebce8f33cc 100644 (file)
@@ -358,7 +358,6 @@ dialog.addmapsource.sourcename=Name der Quelle
 dialog.addmapsource.layer1url=URL f\u00fcr erste Ebene
 dialog.addmapsource.layer2url=URL f\u00fcr obere Ebene (falls n\u00f6tig)
 dialog.addmapsource.maxzoom=Maximales Zoom
 dialog.addmapsource.layer1url=URL f\u00fcr erste Ebene
 dialog.addmapsource.layer2url=URL f\u00fcr obere Ebene (falls n\u00f6tig)
 dialog.addmapsource.maxzoom=Maximales Zoom
-dialog.addmapsource.cloudstyle=Stilnummer
 dialog.addmapsource.noname=Unbenannt
 dialog.gpsies.column.name=Name des Tracks
 dialog.gpsies.column.length=L\u00e4nge
 dialog.addmapsource.noname=Unbenannt
 dialog.gpsies.column.name=Name des Tracks
 dialog.gpsies.column.length=L\u00e4nge
@@ -561,6 +560,9 @@ dialog.weather.day.thursday=Donnerstag
 dialog.weather.day.friday=Freitag
 dialog.weather.day.saturday=Samstag
 dialog.weather.day.sunday=Sonntag
 dialog.weather.day.friday=Freitag
 dialog.weather.day.saturday=Samstag
 dialog.weather.day.sunday=Sonntag
+dialog.weather.wind=Wind
+dialog.weather.temp=Temp
+dialog.weather.humidity=R.L.
 dialog.weather.creditnotice=Diese Daten wurden von openweathermap.org zur Verf\u00fcgung gestellt. Die Webseite hat mehr Information.
 
 # 3d window
 dialog.weather.creditnotice=Diese Daten wurden von openweathermap.org zur Verf\u00fcgung gestellt. Die Webseite hat mehr Information.
 
 # 3d window
@@ -601,6 +603,7 @@ confirm.rotatephoto=Foto gedreht
 confirm.running=In Bearbeitung ...
 confirm.lookupsrtm=Es wurden %d H\u00f6henwerte gefunden
 confirm.downloadsrtm=Es wurden %d Dateien heruntergeladen
 confirm.running=In Bearbeitung ...
 confirm.lookupsrtm=Es wurden %d H\u00f6henwerte gefunden
 confirm.downloadsrtm=Es wurden %d Dateien heruntergeladen
+confirm.downloadsrtm.1=Es wurde %d Datei heruntergeladen
 confirm.downloadsrtm.none=Keine Dateien heruntergeladen, alle waren schon gespeichert.
 confirm.deletefieldvalues=Feldwerte gel\u00f6scht
 confirm.audioload=Audiodateien geladen
 confirm.downloadsrtm.none=Keine Dateien heruntergeladen, alle waren schon gespeichert.
 confirm.deletefieldvalues=Feldwerte gel\u00f6scht
 confirm.audioload=Audiodateien geladen
index fd56f48b79e328e2ac9626e2d9923993e0273564..7e9b304cd6f233f897b576de1d18f91511b65f19 100644 (file)
@@ -353,7 +353,6 @@ dialog.addmapsource.sourcename=Sourcename
 dialog.addmapsource.layer1url=URL f\u00fcr erschti Ebene
 dialog.addmapsource.layer2url=URL f\u00fcr oberi Ebene (falls n\u00f6tig)
 dialog.addmapsource.maxzoom=Maximali Zoom
 dialog.addmapsource.layer1url=URL f\u00fcr erschti Ebene
 dialog.addmapsource.layer2url=URL f\u00fcr oberi Ebene (falls n\u00f6tig)
 dialog.addmapsource.maxzoom=Maximali Zoom
-dialog.addmapsource.cloudstyle=Stilnummere
 dialog.addmapsource.noname=Unbenannt
 dialog.gpsies.column.name=Track Name
 dialog.gpsies.column.length=L\u00e4nge
 dialog.addmapsource.noname=Unbenannt
 dialog.gpsies.column.name=Track Name
 dialog.gpsies.column.length=L\u00e4nge
@@ -556,6 +555,9 @@ dialog.weather.day.thursday=Duunschtig
 dialog.weather.day.friday=Friitig
 dialog.weather.day.saturday=Samschtig
 dialog.weather.day.sunday=Sunntig
 dialog.weather.day.friday=Friitig
 dialog.weather.day.saturday=Samschtig
 dialog.weather.day.sunday=Sunntig
+dialog.weather.wind=Wind
+dialog.weather.temp=Temp
+dialog.weather.humidity=R.L.
 dialog.weather.creditnotice=Diese Date sin vo openweathermap.org zur Verf\u00fcegig gestellt worde. Uf d Websiite h\u00e4ts no meh Infos.
 
 # 3d window
 dialog.weather.creditnotice=Diese Date sin vo openweathermap.org zur Verf\u00fcegig gestellt worde. Uf d Websiite h\u00e4ts no meh Infos.
 
 # 3d window
@@ -596,7 +598,8 @@ confirm.rotatephoto=F\u00f6teli umgedr\u00e4it worde
 confirm.running=Am Laufe ...
 confirm.lookupsrtm=Es sin %d H\u00f6henwerte gfunde
 confirm.downloadsrtm=Es sin %d Files abeglade
 confirm.running=Am Laufe ...
 confirm.lookupsrtm=Es sin %d H\u00f6henwerte gfunde
 confirm.downloadsrtm=Es sin %d Files abeglade
-confirm.downloadsrtm.none=Kei Files abeglade, die sin scho da gsi.
+confirm.downloadsrtm.1=Sisch %d File abeglade
+confirm.downloadsrtm.none=Kei Files abeglade, die sin alli scho da gsi.
 confirm.deletefieldvalues=Feldw\u00e4rte gl\u00f6scht worde
 confirm.audioload=Audiofiles glade worde
 confirm.media.removed=entf\u00e4rnt
 confirm.deletefieldvalues=Feldw\u00e4rte gl\u00f6scht worde
 confirm.audioload=Audiofiles glade worde
 confirm.media.removed=entf\u00e4rnt
index 03d04dfc528566bfca8cdd245829478909dabb8c..bfef0dfcd3c42b44cdfc23b2ad76e6cf3488aadb 100644 (file)
@@ -358,7 +358,6 @@ dialog.addmapsource.sourcename=Name of source
 dialog.addmapsource.layer1url=URL of first layer
 dialog.addmapsource.layer2url=Optional URL of second layer
 dialog.addmapsource.maxzoom=Maximum zoom level
 dialog.addmapsource.layer1url=URL of first layer
 dialog.addmapsource.layer2url=Optional URL of second layer
 dialog.addmapsource.maxzoom=Maximum zoom level
-dialog.addmapsource.cloudstyle=Style number
 dialog.addmapsource.noname=Unnamed
 dialog.gpsies.column.name=Track name
 dialog.gpsies.column.length=Length
 dialog.addmapsource.noname=Unnamed
 dialog.gpsies.column.name=Track name
 dialog.gpsies.column.length=Length
@@ -561,6 +560,9 @@ dialog.weather.day.thursday=Thursday
 dialog.weather.day.friday=Friday
 dialog.weather.day.saturday=Saturday
 dialog.weather.day.sunday=Sunday
 dialog.weather.day.friday=Friday
 dialog.weather.day.saturday=Saturday
 dialog.weather.day.sunday=Sunday
+dialog.weather.wind=Wind
+dialog.weather.temp=Temp
+dialog.weather.humidity=Humidity
 dialog.weather.creditnotice=This data is made available by openweathermap.org. Their website has more details.
 
 # 3d window
 dialog.weather.creditnotice=This data is made available by openweathermap.org. Their website has more details.
 
 # 3d window
@@ -601,7 +603,8 @@ confirm.createpoint=point created
 confirm.running=Running ...
 confirm.lookupsrtm=Found %d altitude values
 confirm.downloadsrtm=Downloaded %d files to the cache
 confirm.running=Running ...
 confirm.lookupsrtm=Found %d altitude values
 confirm.downloadsrtm=Downloaded %d files to the cache
-confirm.downloadsrtm.none=No files downloaded, they were already in the cache.
+confirm.downloadsrtm.1=Downloaded %d file to the cache
+confirm.downloadsrtm.none=No files downloaded, they were already in the cache
 confirm.deletefieldvalues=Field values deleted
 confirm.audioload=Audio files added
 confirm.correlateaudios.single=audio was correlated
 confirm.deletefieldvalues=Field values deleted
 confirm.audioload=Audio files added
 confirm.correlateaudios.single=audio was correlated
index 928d027dbc5180d6bd9b9ced150ed53aa0544eaf..a28dd50c88ccbf20f9e6283a50cc3b5b4c74fb99 100644 (file)
@@ -8,6 +8,7 @@ function.setcolours=Set colors
 dialog.exportkml.trackcolour=Track color
 dialog.saveconfig.prune.languagecode=Language code (EN_US)
 dialog.setcolours.intro=Click on a color patch to change the color
 dialog.exportkml.trackcolour=Track color
 dialog.saveconfig.prune.languagecode=Language code (EN_US)
 dialog.setcolours.intro=Click on a color patch to change the color
+dialog.colourchooser.title=Choose color
 
 # Measurement units
 units.metres=Meters
 
 # Measurement units
 units.metres=Meters
index 182e6700b94c5564fa32b4c0b78e461fc0d9d87a..b752c7cd1a295f9145ec425ec6a950ce30099325 100644 (file)
@@ -105,6 +105,8 @@ function.fullrangedetails=Detalles adicionales de rango
 function.estimatetime=Estimar duraci\u00f3n
 function.setmapbg=Configurar fondo de mapa
 function.setpaths=Configurar rutas del programas
 function.estimatetime=Estimar duraci\u00f3n
 function.setmapbg=Configurar fondo de mapa
 function.setpaths=Configurar rutas del programas
+function.splitsegments=Segmentar el track
+function.sewsegments=Ensamblar los segmentos
 function.getgpsies=Bajar ruta de Gpsies
 function.uploadgpsies=Subir recorrido a Gpsies
 function.lookupsrtm=Obtener altitudes de SRTM
 function.getgpsies=Bajar ruta de Gpsies
 function.uploadgpsies=Subir recorrido a Gpsies
 function.lookupsrtm=Obtener altitudes de SRTM
@@ -193,7 +195,11 @@ dialog.gpsbabel.filter.discard.intro=Desechar puntos si
 dialog.gpsbabel.filter.discard.hdop=Hdop >
 dialog.gpsbabel.filter.discard.vdop=Vdop >
 dialog.gpsbabel.filter.discard.numsats=N\u00famero de sat\u00e9lites <
 dialog.gpsbabel.filter.discard.hdop=Hdop >
 dialog.gpsbabel.filter.discard.vdop=Vdop >
 dialog.gpsbabel.filter.discard.numsats=N\u00famero de sat\u00e9lites <
-dialog.gpsbabel.filter.simplify.maxpoints=Numero de puntos <
+dialog.gpsbabel.filter.discard.nofix=Posici\u00f3n no precisa
+dialog.gpsbabel.filter.discard.unknownfix=Precisi\u00f3n desconocida
+dialog.gpsbabel.filter.simplify.intro=Desechar puntos hasta
+dialog.gpsbabel.filter.simplify.maxpoints=N\u00famero de puntos <
+dialog.gpsbabel.filter.simplify.maxerror=o desviaci\u00f3n <
 dialog.gpsbabel.filter.distance.distance=Si distancia <
 dialog.gpsbabel.filter.distance.time=y differencia horaria <
 dialog.gpsbabel.filter.interpolate.distance=Si distancia >
 dialog.gpsbabel.filter.distance.distance=Si distancia <
 dialog.gpsbabel.filter.distance.time=y differencia horaria <
 dialog.gpsbabel.filter.interpolate.distance=Si distancia >
@@ -226,6 +232,9 @@ dialog.exportgpx.encoding=Codificaci\u00f3n
 dialog.exportgpx.encoding.system=Sistema
 dialog.exportgpx.encoding.utf8=UTF-8
 dialog.3d.useterrain=Terreno
 dialog.exportgpx.encoding.system=Sistema
 dialog.exportgpx.encoding.utf8=UTF-8
 dialog.3d.useterrain=Terreno
+dialog.3d.terraingridsize=Dimensi\u00f3n de la cuadr\u00edcula
+dialog.exportpov.cannotmakebaseimage=Fallo al guardar la imagen
+dialog.exportpov.baseimage=Imagen de mapa
 dialog.exportpov.text=Introduca los par\u00e1metros para exportar
 dialog.exportpov.font=Fuente
 dialog.exportpov.camerax=C\u00e1mara X
 dialog.exportpov.text=Introduca los par\u00e1metros para exportar
 dialog.exportpov.font=Fuente
 dialog.exportpov.camerax=C\u00e1mara X
@@ -234,7 +243,7 @@ dialog.exportpov.cameraz=C\u00e1mara Z
 dialog.exportpov.modelstyle=Estilo
 dialog.exportpov.ballsandsticks=Balas en palos
 dialog.exportpov.tubesandwalls=Tubos y paredes
 dialog.exportpov.modelstyle=Estilo
 dialog.exportpov.ballsandsticks=Balas en palos
 dialog.exportpov.tubesandwalls=Tubos y paredes
-dialog.3d.warningtracksize=Este track contiene un gran numero de puntos. Puede ser que Java3D no los pueda visualizar. Est\u00e1 seguro de que desea continuar?
+dialog.3d.warningtracksize=Este track contiene un gran n\u00famero de puntos. Puede ser que Java3D no los pueda visualizar. Est\u00e1 seguro de que desea continuar?
 dialog.baseimage.title=Imagen de mapa
 dialog.baseimage.mapsource=Proveedor de mapas
 dialog.baseimage.useimage=Usar imagen
 dialog.baseimage.title=Imagen de mapa
 dialog.baseimage.mapsource=Proveedor de mapas
 dialog.baseimage.useimage=Usar imagen
@@ -248,6 +257,7 @@ dialog.exportsvg.theta=\u00c1ngulo de elevaci\u00f3n
 dialog.exportsvg.gradients=Usar degradado para sombras
 dialog.exportimage.drawtrack=Dibujar track
 dialog.exportimage.drawtrackpoints=Dibujar puntos del track
 dialog.exportsvg.gradients=Usar degradado para sombras
 dialog.exportimage.drawtrack=Dibujar track
 dialog.exportimage.drawtrackpoints=Dibujar puntos del track
+dialog.exportimage.textscalepercent=Agrandamiento del texto (%)
 dialog.pointtype.desc=Salvar los siguientes tipos de puntos:
 dialog.pointtype.track=Puntos del track
 dialog.pointtype.waypoint=Waypoints
 dialog.pointtype.desc=Salvar los siguientes tipos de puntos:
 dialog.pointtype.track=Puntos del track
 dialog.pointtype.waypoint=Waypoints
@@ -257,14 +267,15 @@ dialog.pointtype.selection=Solo selecci\u00f3n
 dialog.confirmreversetrack.title=Confirmar inversi\u00f3n
 dialog.confirmreversetrack.text=Este track contiene informaci\u00f3n sobre la fecha, que estar\u00e1 fuera de secuencia despu\u00e9s de la inversi\u00f3n. \u00bfEst\u00e1 seguro que desea invertir esta secci\u00f3n?
 dialog.confirmcutandmove.title=Confirmar accion cortar/pegar
 dialog.confirmreversetrack.title=Confirmar inversi\u00f3n
 dialog.confirmreversetrack.text=Este track contiene informaci\u00f3n sobre la fecha, que estar\u00e1 fuera de secuencia despu\u00e9s de la inversi\u00f3n. \u00bfEst\u00e1 seguro que desea invertir esta secci\u00f3n?
 dialog.confirmcutandmove.title=Confirmar accion cortar/pegar
-dialog.confirmcutandmove.text=Este track contiene informaci\u00f3n sobre la fecha, que estar\u00e1 fuera de secuencia despu\u00e9s de mover.\n\u00bfEsta seguro que desea mover esta secci\u00f3n?
+dialog.confirmcutandmove.text=Este track contiene informaci\u00f3n sobre la fecha, que estar\u00e1 fuera de secuencia despu\u00e9s de mover.\n\u00bfEst\u00e1 seguro que desea mover esta secci\u00f3n?
 dialog.interpolate.parameter.text=N\u00famero de los puntos a insertar entre los puntos elegidos
 dialog.interpolate.parameter.text=N\u00famero de los puntos a insertar entre los puntos elegidos
+dialog.interpolate.betweenwaypoints=Interpolar entre los waypoints?
 dialog.undo.title=Deshacer
 dialog.undo.pretext=Por favor, seleccione la operaci\u00f3n(es) a deshacer
 dialog.undo.none.title=No se puede deshacer
 dialog.undo.none.text=Ninguna operaci\u00f3n a deshacer
 dialog.clearundo.title=Despejar la lista de deshacer
 dialog.undo.title=Deshacer
 dialog.undo.pretext=Por favor, seleccione la operaci\u00f3n(es) a deshacer
 dialog.undo.none.title=No se puede deshacer
 dialog.undo.none.text=Ninguna operaci\u00f3n a deshacer
 dialog.clearundo.title=Despejar la lista de deshacer
-dialog.clearundo.text=\u00bfEsta seguro que desea despejar la lista de deshacer?, \u00a1se perder\u00e1 toda la informaci\u00f3n!
+dialog.clearundo.text=\u00bfEst\u00e1 seguro que desea despejar la lista de deshacer?, \u00a1se perder\u00e1 toda la informaci\u00f3n!
 dialog.pointedit.title=Editar punto
 dialog.pointedit.intro=Seleccione cada campo para modificar el valor
 dialog.pointedit.table.field=Campo
 dialog.pointedit.title=Editar punto
 dialog.pointedit.intro=Seleccione cada campo para modificar el valor
 dialog.pointedit.table.field=Campo
@@ -310,19 +321,27 @@ dialog.distances.currentpoint=Punto actual
 dialog.distances.toofewpoints=Esta funcion necesita "waypoints" para poder calcular las distancias entre ellos
 dialog.fullrangedetails.intro=Aqui estan los detalles para la selecci\u00f3n de rangos
 dialog.estimatetime.details=Detalles
 dialog.distances.toofewpoints=Esta funcion necesita "waypoints" para poder calcular las distancias entre ellos
 dialog.fullrangedetails.intro=Aqui estan los detalles para la selecci\u00f3n de rangos
 dialog.estimatetime.details=Detalles
+dialog.estimatetime.gentle=Inclinaci\u00f3n peque\u00f1a
+dialog.estimatetime.steep=Inclinaci\u00f3n grande
 dialog.estimatetime.climb=Ascenso
 dialog.estimatetime.descent=Descenso
 dialog.estimatetime.parameters=Par\u00e1metros
 dialog.estimatetime.climb=Ascenso
 dialog.estimatetime.descent=Descenso
 dialog.estimatetime.parameters=Par\u00e1metros
+dialog.estimatetime.parameters.timefor=Duraci\u00f3n para
 dialog.estimatetime.results=Resultados
 dialog.estimatetime.results.estimatedtime=Duraci\u00f3n estimada
 dialog.estimatetime.results.actualtime=Duraci\u00f3n real
 dialog.estimatetime.results=Resultados
 dialog.estimatetime.results.estimatedtime=Duraci\u00f3n estimada
 dialog.estimatetime.results.actualtime=Duraci\u00f3n real
+dialog.learnestimationparams.combinedresults=Resultados combinados
+dialog.learnestimationparams.weight.100pccurrent=Mantener datos actuales
+dialog.learnestimationparams.weight.current=actuales
+dialog.learnestimationparams.weight.calculated=calculados
+dialog.learnestimationparams.weight.50pc=La media entre actuales y calculados
+dialog.learnestimationparams.weight.100pccalculated=Nuevos datos calculados
 dialog.setmapbg.intro=Seleccione un proveedor de mapas o a\u00f1ada uno nuevo
 dialog.addmapsource.title=A\u00f1adir un proveedor de mapas
 dialog.addmapsource.sourcename=Nombre del proveedor
 dialog.addmapsource.layer1url=URL de la primera capa
 dialog.addmapsource.layer2url=URL opcional de la segunda capa
 dialog.addmapsource.maxzoom=M\u00e1ximo nivel de zoom
 dialog.setmapbg.intro=Seleccione un proveedor de mapas o a\u00f1ada uno nuevo
 dialog.addmapsource.title=A\u00f1adir un proveedor de mapas
 dialog.addmapsource.sourcename=Nombre del proveedor
 dialog.addmapsource.layer1url=URL de la primera capa
 dialog.addmapsource.layer2url=URL opcional de la segunda capa
 dialog.addmapsource.maxzoom=M\u00e1ximo nivel de zoom
-dialog.addmapsource.cloudstyle=N\u00famero del estilo
 dialog.addmapsource.noname=Innominada
 dialog.gpsies.column.name=Nombre del track
 dialog.gpsies.column.length=Distancia
 dialog.addmapsource.noname=Innominada
 dialog.gpsies.column.name=Nombre del track
 dialog.gpsies.column.length=Distancia
@@ -432,7 +451,7 @@ dialog.about.credits.devtools=Herramientas de desarrollo
 dialog.about.credits.othertools=Otras herramientas
 dialog.about.credits.thanks=Gracias a
 dialog.about.readme=Readme
 dialog.about.credits.othertools=Otras herramientas
 dialog.about.credits.thanks=Gracias a
 dialog.about.readme=Readme
-dialog.checkversion.error=El numero de versi\u00f3n no pudo ser verificada.\n Por favor verificar la conexi\u00f3n de Internet
+dialog.checkversion.error=El n\u00famero de versi\u00f3n no pudo ser verificada.\n Por favor verificar la conexi\u00f3n de Internet
 dialog.checkversion.uptodate=Esta usted utilizando la \u00faltima versi\u00f3n de GpsPrune
 dialog.checkversion.newversion1=\u00a1Una nueva versi\u00f3n de GpsPrune est\u00e1 disponible! La \u00faltima es ahora la versi\u00f3n
 dialog.checkversion.newversion2=.
 dialog.checkversion.uptodate=Esta usted utilizando la \u00faltima versi\u00f3n de GpsPrune
 dialog.checkversion.newversion1=\u00a1Una nueva versi\u00f3n de GpsPrune est\u00e1 disponible! La \u00faltima es ahora la versi\u00f3n
 dialog.checkversion.newversion2=.
@@ -458,7 +477,6 @@ dialog.saveconfig.prune.mapsource=Proveedor de mapas seleccionado
 dialog.saveconfig.prune.mapsourcelist=Proveedor de mapas
 dialog.saveconfig.prune.diskcache=Memoria intermedia de mapas
 dialog.saveconfig.prune.kmzimagewidth=Ancho de im\u00e1genes en KMZ
 dialog.saveconfig.prune.mapsourcelist=Proveedor de mapas
 dialog.saveconfig.prune.diskcache=Memoria intermedia de mapas
 dialog.saveconfig.prune.kmzimagewidth=Ancho de im\u00e1genes en KMZ
-dialog.saveconfig.prune.kmzimageheight=Alto de im\u00e1genes en KMZ
 dialog.saveconfig.prune.colourscheme=Color de esquema
 dialog.saveconfig.prune.linewidth=Ancho de l\u00ednea
 dialog.saveconfig.prune.kmltrackcolour=Color de pista de KML
 dialog.saveconfig.prune.colourscheme=Color de esquema
 dialog.saveconfig.prune.linewidth=Ancho de l\u00ednea
 dialog.saveconfig.prune.kmltrackcolour=Color de pista de KML
@@ -507,6 +525,14 @@ dialog.deletefieldvalues.nofields=No hay campos a eliminar para el rango actual
 dialog.setlinewidth.text=Introduzca la anchura de las l\u00edneas a dibujar para los recorridos (1-4)
 dialog.downloadosm.desc=Confirmar la descarga de datos en bruto de OSM para el \u00e1rea especificada.
 dialog.searchwikipedianames.search=Buscar:
 dialog.setlinewidth.text=Introduzca la anchura de las l\u00edneas a dibujar para los recorridos (1-4)
 dialog.downloadosm.desc=Confirmar la descarga de datos en bruto de OSM para el \u00e1rea especificada.
 dialog.searchwikipedianames.search=Buscar:
+dialog.weather.location=Localidad
+dialog.weather.update=Actualizado
+dialog.weather.sunrise=Salida del sol
+dialog.weather.sunset=Puesta de sol
+dialog.weather.temperatureunits=Temperaturas
+dialog.weather.currentforecast=El tiempo actual
+dialog.weather.dailyforecast=Pron\u00f3stico diariamente
+dialog.weather.3hourlyforecast=Pron\u00f3stico hora a hora
 dialog.weather.day.now=Tiempo actual
 dialog.weather.day.today=Hoy
 dialog.weather.day.tomorrow=Ma\u00f1ana
 dialog.weather.day.now=Tiempo actual
 dialog.weather.day.today=Hoy
 dialog.weather.day.tomorrow=Ma\u00f1ana
@@ -517,6 +543,9 @@ dialog.weather.day.thursday=Jueves
 dialog.weather.day.friday=Viernes
 dialog.weather.day.saturday=S\u00e1bado
 dialog.weather.day.sunday=Domingo
 dialog.weather.day.friday=Viernes
 dialog.weather.day.saturday=S\u00e1bado
 dialog.weather.day.sunday=Domingo
+dialog.weather.wind=Viento
+dialog.weather.temp=Temp
+dialog.weather.humidity=Humedad
 
 # 3d window
 dialog.3d.title=GpsPrune vista 3-D
 
 # 3d window
 dialog.3d.title=GpsPrune vista 3-D
@@ -553,6 +582,8 @@ confirm.createpoint=punto creado
 confirm.rotatephoto=foto rotada
 confirm.running=Trabajando ...
 confirm.lookupsrtm=Encontrados %d valor de altitud para la funci\u00f3n de b\u00fasqueda SRTM
 confirm.rotatephoto=foto rotada
 confirm.running=Trabajando ...
 confirm.lookupsrtm=Encontrados %d valor de altitud para la funci\u00f3n de b\u00fasqueda SRTM
+confirm.downloadsrtm=Descargado %d archivos
+confirm.downloadsrtm.1=Descargado %d archivo
 confirm.deletefieldvalues=Valores del campo eliminados
 confirm.audioload=A\u00f1adidos archivos de audio
 confirm.correlateaudios.single=El audio fue correlacionado
 confirm.deletefieldvalues=Valores del campo eliminados
 confirm.audioload=A\u00f1adidos archivos de audio
 confirm.correlateaudios.single=El audio fue correlacionado
@@ -577,6 +608,7 @@ button.close=Cerrar
 button.continue=Contin\u00fae
 button.yes=Si
 button.no=No
 button.continue=Contin\u00fae
 button.yes=Si
 button.no=No
+button.always=Si, siempre
 button.yestoall=Si por todo
 button.notoall=No por todo
 button.select=Seleccionar
 button.yestoall=Si por todo
 button.notoall=No por todo
 button.select=Seleccionar
@@ -735,6 +767,8 @@ undo.deletemarked=eliminar puntos
 undo.insert=insertar puntos
 undo.reverse=invertir rango
 undo.mergetracksegments=unir los segmentos del track
 undo.insert=insertar puntos
 undo.reverse=invertir rango
 undo.mergetracksegments=unir los segmentos del track
+undo.splitsegments=segmentar el track
+undo.sewsegments=ensamblar los segmentos del track
 undo.addtimeoffset=a\u00f1adir margen de tiempo
 undo.addaltitudeoffset=a\u00f1adir margen de altitud
 undo.rearrangewaypoints=reordenar waypoints
 undo.addtimeoffset=a\u00f1adir margen de tiempo
 undo.addaltitudeoffset=a\u00f1adir margen de altitud
 undo.rearrangewaypoints=reordenar waypoints
@@ -788,7 +822,12 @@ error.lookupsrtm.nonefound=No se encontraron valores de altitud
 error.lookupsrtm.nonerequired=Todos los puntos tienen altitudes, as\u00ed que no hay nada que buscar.
 error.gpsies.uploadnotok=El servidor de gpsies ha devuelto el mensaje
 error.gpsies.uploadfailed=La carga ha fallado con el error
 error.lookupsrtm.nonerequired=Todos los puntos tienen altitudes, as\u00ed que no hay nada que buscar.
 error.gpsies.uploadnotok=El servidor de gpsies ha devuelto el mensaje
 error.gpsies.uploadfailed=La carga ha fallado con el error
+error.showphoto.failed=Fallo al cargar la foto
 error.playaudiofailed=Fallo reproduciendo archivo de audio
 error.cache.notthere=No se encontr\u00f3 la carpeta del cache de recuadros
 error.cache.empty=La carpeta del cache de recuadros esta vac\u00edo
 error.cache.cannotdelete=No se pudieron borrar recuadros
 error.playaudiofailed=Fallo reproduciendo archivo de audio
 error.cache.notthere=No se encontr\u00f3 la carpeta del cache de recuadros
 error.cache.empty=La carpeta del cache de recuadros esta vac\u00edo
 error.cache.cannotdelete=No se pudieron borrar recuadros
+error.interpolate.invalidparameter=El n\u00famero de puntos necesita ser entre 1 y 1000
+error.tracksplit.nosplit=Imposible segmentar el track
+error.downloadsrtm.nocache=Imposible guardar los archivos.\nPor favor, compruebe el cache.
+error.sewsegments.nothingdone=Imposible ensamblar los segmentos.\nEl track tiene ahora %d segmentos.
index 4e7ceef17082c14fb7c967032ac640f87c9a7f34..d271c279a7531c2ae707d2ebfcdb6013c750d267 100644 (file)
@@ -7,6 +7,7 @@ menu.file.addphotos=Ajouter photos
 menu.file.recentfiles=Fichiers r\u00e9cents
 menu.file.save=Enregistrer
 menu.file.exit=Quitter
 menu.file.recentfiles=Fichiers r\u00e9cents
 menu.file.save=Enregistrer
 menu.file.exit=Quitter
+menu.online=En ligne
 menu.track=Trace
 menu.track.undo=Annuler
 menu.track.clearundo=Purger la liste d'annulation
 menu.track=Trace
 menu.track.undo=Annuler
 menu.track.clearundo=Purger la liste d'annulation
@@ -57,6 +58,7 @@ menu.map.editmode=Mode \u00e9dition
 
 # Alt keys for menus
 altkey.menu.file=F
 
 # Alt keys for menus
 altkey.menu.file=F
+altkey.menu.online=L
 altkey.menu.track=T
 altkey.menu.range=E
 altkey.menu.point=P
 altkey.menu.track=T
 altkey.menu.range=E
 altkey.menu.point=P
@@ -103,9 +105,12 @@ function.fullrangedetails=Montrer tous les d\u00e9tails
 function.estimatetime=Temps estim\u00e9
 function.setmapbg=D\u00e9finir le fond de carte
 function.setpaths=D\u00e9finir les chemins des programmes
 function.estimatetime=Temps estim\u00e9
 function.setmapbg=D\u00e9finir le fond de carte
 function.setpaths=D\u00e9finir les chemins des programmes
+function.splitsegments=S\u00e9pare les segments
+function.sewsegments=R\u00e9unis les segments
 function.getgpsies=R\u00e9cup\u00e9rer les traces Gpsies
 function.uploadgpsies=T\u00e9l\u00e9charger la trace sur Gpsies
 function.lookupsrtm=R\u00e9cup\u00e9rer les altitudes depuis SRTM
 function.getgpsies=R\u00e9cup\u00e9rer les traces Gpsies
 function.uploadgpsies=T\u00e9l\u00e9charger la trace sur Gpsies
 function.lookupsrtm=R\u00e9cup\u00e9rer les altitudes depuis SRTM
+function.downloadsrtm=T\u00e9l\u00e9charger les donn\u00e9es SRTM
 function.getwikipedia=Obtenir les articles de Wikip\u00e9dia \u00e0 proximit\u00e9
 function.searchwikipedianames=Rechercher dans Wikip\u00e9dia par nom
 function.downloadosm=T\u00e9l\u00e9charger les donn\u00e9es OSM de la zone
 function.getwikipedia=Obtenir les articles de Wikip\u00e9dia \u00e0 proximit\u00e9
 function.searchwikipedianames=Rechercher dans Wikip\u00e9dia par nom
 function.downloadosm=T\u00e9l\u00e9charger les donn\u00e9es OSM de la zone
@@ -163,6 +168,8 @@ dialog.openoptions.deliminfo.norecords=Pas d'enregistrements
 dialog.openoptions.altitudeunits=Unit\u00e9s d'altitude
 dialog.openoptions.speedunits=Unit\u00e9s de vitesse
 dialog.openoptions.vertspeedunits=Unit\u00e9s de vitesse verticale
 dialog.openoptions.altitudeunits=Unit\u00e9s d'altitude
 dialog.openoptions.speedunits=Unit\u00e9s de vitesse
 dialog.openoptions.vertspeedunits=Unit\u00e9s de vitesse verticale
+dialog.openoptions.vspeed.positiveup=Vitesse positive en montant
+dialog.openoptions.vspeed.positivedown=Vitesse positive en bas
 dialog.open.contentsdoubled=Ce fichier contient deux copies de chaque point,\nune fois comme waypoint, une autre comme point de trace.
 dialog.selecttracks.intro=S\u00e9lectionner la ou les traces \u00e0 charger
 dialog.selecttracks.noname=Sans titre
 dialog.open.contentsdoubled=Ce fichier contient deux copies de chaque point,\nune fois comme waypoint, une autre comme point de trace.
 dialog.selecttracks.intro=S\u00e9lectionner la ou les traces \u00e0 charger
 dialog.selecttracks.noname=Sans titre
@@ -181,12 +188,19 @@ dialog.gpssend.sendwaypoints=Envoyer les waypoints
 dialog.gpssend.sendtracks=Envoyer les traces
 dialog.gpssend.trackname=Nom de la trace
 dialog.gpsbabel.filters=Filtres
 dialog.gpssend.sendtracks=Envoyer les traces
 dialog.gpssend.trackname=Nom de la trace
 dialog.gpsbabel.filters=Filtres
+dialog.addfilter.title=Ajouter un filtre
 dialog.gpsbabel.filter.discard=Jeter
 dialog.gpsbabel.filter.simplify=Simplifier
 dialog.gpsbabel.filter.interpolate=Interpoler
 dialog.gpsbabel.filter.discard.intro=Jeter les points si
 dialog.gpsbabel.filter.discard.hdop=Hdop >
 dialog.gpsbabel.filter.discard.vdop=Vdop >
 dialog.gpsbabel.filter.discard=Jeter
 dialog.gpsbabel.filter.simplify=Simplifier
 dialog.gpsbabel.filter.interpolate=Interpoler
 dialog.gpsbabel.filter.discard.intro=Jeter les points si
 dialog.gpsbabel.filter.discard.hdop=Hdop >
 dialog.gpsbabel.filter.discard.vdop=Vdop >
+dialog.gpsbabel.filter.discard.numsats=Nombre de satellites <
+dialog.gpsbabel.filter.discard.nofix=Point n'a pas fix
+dialog.gpsbabel.filter.discard.unknownfix=Point a une fix inconnue
+dialog.gpsbabel.filter.simplify.intro=Effacer les points jusque
+dialog.gpsbabel.filter.simplify.maxpoints=Nombre de points <
+dialog.gpsbabel.filter.simplify.maxerror=ou erreur <
 dialog.gpsbabel.filter.distance=Distance
 dialog.gpsbabel.filter.distance.distance=Si la distance <
 dialog.gpsbabel.filter.distance.time=et difference de temps <
 dialog.gpsbabel.filter.distance=Distance
 dialog.gpsbabel.filter.distance.distance=Si la distance <
 dialog.gpsbabel.filter.distance.time=et difference de temps <
@@ -228,6 +242,9 @@ dialog.exportpov.modelstyle=Style du mod\u00e8le
 dialog.exportpov.ballsandsticks=Points et b\u00e2tons
 dialog.exportpov.tubesandwalls=Tubes et murs
 dialog.3d.warningtracksize=Cette trace poss\u00e8de un grand nombre de points, Java3D peut ne pas pouvoir l'afficher.\n\u00cates-vous s\u00fbr de vouloir continuer ?
 dialog.exportpov.ballsandsticks=Points et b\u00e2tons
 dialog.exportpov.tubesandwalls=Tubes et murs
 dialog.3d.warningtracksize=Cette trace poss\u00e8de un grand nombre de points, Java3D peut ne pas pouvoir l'afficher.\n\u00cates-vous s\u00fbr de vouloir continuer ?
+dialog.3d.useterrain=Montrer terrain
+dialog.3d.terraingridsize=Taille de la grille
+dialog.exportpov.baseimage=Image de la carte
 dialog.baseimage.title=Image de la carte
 dialog.baseimage.useimage=Utiliser image
 dialog.baseimage.mapsource=Source de cartes
 dialog.baseimage.title=Image de la carte
 dialog.baseimage.useimage=Utiliser image
 dialog.baseimage.mapsource=Source de cartes
@@ -239,6 +256,8 @@ dialog.exportsvg.text=S\u00e9lectionner les param\u00e8tres de l'export SVG
 dialog.exportsvg.phi=Angle d'azimuth \u03d5
 dialog.exportsvg.theta=Angle d'\u00e9l\u00e9vation \u03b8
 dialog.exportsvg.gradients=Utiliser des d\u00e9grad\u00e9s pour l'ombrage
 dialog.exportsvg.phi=Angle d'azimuth \u03d5
 dialog.exportsvg.theta=Angle d'\u00e9l\u00e9vation \u03b8
 dialog.exportsvg.gradients=Utiliser des d\u00e9grad\u00e9s pour l'ombrage
+dialog.exportimage.drawtrack=Dessiner la trace sur la carte
+dialog.exportimage.drawtrackpoints=Dessiner les points de trace
 dialog.pointtype.desc=Sauvegarder ces types de points:
 dialog.pointtype.track=Points de la trace
 dialog.pointtype.waypoint=Waypoints
 dialog.pointtype.desc=Sauvegarder ces types de points:
 dialog.pointtype.track=Points de la trace
 dialog.pointtype.waypoint=Waypoints
@@ -260,6 +279,7 @@ dialog.clearundo.text=\u00cates-vous s\u00fbr de vouloir effacer la liste d'annu
 dialog.pointedit.title=\u00c9diter le point
 dialog.pointedit.intro=S\u00e9lectionner chaque champ pour voire et changer la valeur
 dialog.pointedit.table.field=Champ
 dialog.pointedit.title=\u00c9diter le point
 dialog.pointedit.intro=S\u00e9lectionner chaque champ pour voire et changer la valeur
 dialog.pointedit.table.field=Champ
+dialog.pointedit.nofield=Aucun champ choisi
 dialog.pointedit.table.value=Valeur
 dialog.pointnameedit.name=Nom de waypoint
 dialog.pointnameedit.uppercase=CASSE MAJUSCULES
 dialog.pointedit.table.value=Valeur
 dialog.pointnameedit.name=Nom de waypoint
 dialog.pointnameedit.uppercase=CASSE MAJUSCULES
@@ -302,15 +322,23 @@ dialog.distances.toofewpoints=Cette fonction a besoin de waypoints pour calculer
 dialog.fullrangedetails.intro=Voici les d\u00e9tails pour l\u2019\u00e9tendue s\u00e9lectionn\u00e9e
 dialog.fullrangedetails.coltotal=Inclure les cellules vides
 dialog.fullrangedetails.colsegments=Exclure les cellules vides
 dialog.fullrangedetails.intro=Voici les d\u00e9tails pour l\u2019\u00e9tendue s\u00e9lectionn\u00e9e
 dialog.fullrangedetails.coltotal=Inclure les cellules vides
 dialog.fullrangedetails.colsegments=Exclure les cellules vides
+dialog.estimatetime.details=D\u00e9tails
+dialog.estimatetime.steep=Escarp\u00e9
 dialog.estimatetime.climb=Mont\u00e9e
 dialog.estimatetime.descent=Descente
 dialog.estimatetime.climb=Mont\u00e9e
 dialog.estimatetime.descent=Descente
+dialog.estimatetime.parameters=Param\u00e8tres
+dialog.estimatetime.parameters.timefor=Dur\u00e9e pour
+dialog.estimatetime.results=R\u00e9sultats
+dialog.estimatetime.results.estimatedtime=Dur\u00e9e estim\u00e9e
+dialog.estimatetime.results.actualtime=Dur\u00e9e en fait
+dialog.learnestimationparams.averageerror=Erreur en moyenne
+dialog.learnestimationparams.combinedresults=R\u00e9sultats combin\u00e9es
 dialog.setmapbg.intro=S\u00e9lectionnez une source de cartes, ou ajoutez-en une nouvelle
 dialog.addmapsource.title=Ajouter une nouvelle source de cartes
 dialog.addmapsource.sourcename=Nom de la source
 dialog.addmapsource.layer1url=URL de la premi\u00e8re couche
 dialog.addmapsource.layer2url=URL optionnelle de la deuxi\u00e8me couche
 dialog.addmapsource.maxzoom=Niveau de zoom maximum
 dialog.setmapbg.intro=S\u00e9lectionnez une source de cartes, ou ajoutez-en une nouvelle
 dialog.addmapsource.title=Ajouter une nouvelle source de cartes
 dialog.addmapsource.sourcename=Nom de la source
 dialog.addmapsource.layer1url=URL de la premi\u00e8re couche
 dialog.addmapsource.layer2url=URL optionnelle de la deuxi\u00e8me couche
 dialog.addmapsource.maxzoom=Niveau de zoom maximum
-dialog.addmapsource.cloudstyle=Num\u00e9ro du style
 dialog.addmapsource.noname=Sans titre
 dialog.gpsies.column.name=Nom de la trace
 dialog.gpsies.column.length=Distance
 dialog.addmapsource.noname=Sans titre
 dialog.gpsies.column.name=Nom de la trace
 dialog.gpsies.column.length=Distance
@@ -428,7 +456,7 @@ dialog.checkversion.releasedate1=La nouvelle version est sortie le
 dialog.checkversion.releasedate2=.
 dialog.checkversion.download=Pour t\u00e9l\u00e9charger la nouvelle version, aller \u00e0 http://gpsprune.activityworkshop.net/download.html.
 dialog.keys.intro=Vous pouvez utiliser ces raccourcis clavier \u00e0 la place de la souris
 dialog.checkversion.releasedate2=.
 dialog.checkversion.download=Pour t\u00e9l\u00e9charger la nouvelle version, aller \u00e0 http://gpsprune.activityworkshop.net/download.html.
 dialog.keys.intro=Vous pouvez utiliser ces raccourcis clavier \u00e0 la place de la souris
-dialog.keys.keylist=<table><tr><td>Touches-fl\u00e8ches</td><td>Faire d\u00e9filer la carte horizontalement et verticalement</td></tr><tr><td>Ctrl + gauche, Ctrl + droite</td><td>Choisir le point pr\u00e9c\u00e9dent ou suivant</td></tr><tr><td>Ctrl + haut, Ctrl + bas</td><td>Zoomer, s'\u00e9loigner</td></tr><tr><td>Suppr</td><td>Effacer le point courant</td></tr></table>
+dialog.keys.keylist=<table><tr><td>Touches-fl\u00e8ches</td><td>Faire d\u00e9filer la carte horizontalement et verticalement</td></tr><tr><td>Ctrl + gauche, Ctrl + droite</td><td>Choisir le point pr\u00e9c\u00e9dent ou suivant</td></tr><tr><td>Ctrl + haut, Ctrl + bas</td><td>Zoomer, s'\u00e9loigner</td></tr><tr><td>Ctrl + PgUp, PgDown</td><td>Choisir le segment pr\u00e9c\u00e9dent ou suivant</td></tr><tr><td>Ctrl + Home, End</td><td>Choisir le point premier, dernier</td></tr><tr><td>Suppr</td><td>Effacer le point courant</td></tr></table>
 dialog.keys.normalmodifier=Ctrl
 dialog.keys.macmodifier=Command
 dialog.saveconfig.desc=Les param\u00e8tres suivants peuvent \u00eatre sauvegard\u00e9s dans un fichier de configuration:
 dialog.keys.normalmodifier=Ctrl
 dialog.keys.macmodifier=Command
 dialog.saveconfig.desc=Les param\u00e8tres suivants peuvent \u00eatre sauvegard\u00e9s dans un fichier de configuration:
@@ -446,7 +474,6 @@ dialog.saveconfig.prune.mapsource=Carte source s\u00e9lectionn\u00e9e
 dialog.saveconfig.prune.mapsourcelist=Sources de cartes
 dialog.saveconfig.prune.diskcache=Cache de carte
 dialog.saveconfig.prune.kmzimagewidth=Largeur de l'image KMZ
 dialog.saveconfig.prune.mapsourcelist=Sources de cartes
 dialog.saveconfig.prune.diskcache=Cache de carte
 dialog.saveconfig.prune.kmzimagewidth=Largeur de l'image KMZ
-dialog.saveconfig.prune.kmzimageheight=Hauteur de l'image KMZ
 dialog.saveconfig.prune.colourscheme=Mod\u00e8le de couleurs
 dialog.saveconfig.prune.linewidth=Largeur de ligne
 dialog.saveconfig.prune.kmltrackcolour=Couleur de la trace KML
 dialog.saveconfig.prune.colourscheme=Mod\u00e8le de couleurs
 dialog.saveconfig.prune.linewidth=Largeur de ligne
 dialog.saveconfig.prune.kmltrackcolour=Couleur de la trace KML
@@ -514,6 +541,10 @@ dialog.weather.day.thursday=Jeudi
 dialog.weather.day.friday=Vendredi
 dialog.weather.day.saturday=Samedi
 dialog.weather.day.sunday=Dimanche
 dialog.weather.day.friday=Vendredi
 dialog.weather.day.saturday=Samedi
 dialog.weather.day.sunday=Dimanche
+dialog.weather.wind=Vent
+dialog.weather.temp=Temp
+dialog.weather.humidity=Humidit\u00e9
+dialog.weather.creditnotice=Ces donn\u00e9es sont fournies par openweathermap.org. Consultez la page pour plus de d\u00e9tails.
 
 # 3d window
 dialog.3d.title=Vue 3D de GpsPrune
 
 # 3d window
 dialog.3d.title=Vue 3D de GpsPrune
@@ -550,6 +581,9 @@ confirm.createpoint=Point cr\u00e9\u00e9
 confirm.rotatephoto=Photo tourn\u00e9e
 confirm.running=En cours...
 confirm.lookupsrtm=Trouv\u00e9 %d valeurs d'altitude
 confirm.rotatephoto=Photo tourn\u00e9e
 confirm.running=En cours...
 confirm.lookupsrtm=Trouv\u00e9 %d valeurs d'altitude
+confirm.downloadsrtm=%d fichiers ont \u00e9t\u00e9 t\u00e9l\u00e9charg\u00e9s
+confirm.downloadsrtm.1=%d fichier a \u00e9t\u00e9 t\u00e9l\u00e9charg\u00e9
+confirm.downloadsrtm.none=Pas de fichiers ont \u00e9t\u00e9 t\u00e9l\u00e9charg\u00e9s, ils sont d\u00e9j\u00e0 l\u00e0
 confirm.deletefieldvalues=Valeurs effac\u00e9es
 confirm.audioload=Fichiers audio ajout\u00e9s
 confirm.correlateaudios.single=fichier audio a \u00e9t\u00e9 corr\u00e9l\u00e9
 confirm.deletefieldvalues=Valeurs effac\u00e9es
 confirm.audioload=Fichiers audio ajout\u00e9s
 confirm.correlateaudios.single=fichier audio a \u00e9t\u00e9 corr\u00e9l\u00e9
@@ -557,6 +591,10 @@ confirm.correlateaudios.multi=fichiers audio ont \u00e9t\u00e9 corr\u00e9l\u00e9
 
 # Tips
 tip.title=Astuce
 
 # Tips
 tip.title=Astuce
+tip.useamapcache=By setting up a disk cache (Pr\u00e9f\u00e9rences -> Enregistrer les cartes sur le disque)\nyou can speed up the display and reduce network traffic.
+tip.learntimeparams=The results will be more accurate if you use\nTrace -> Learn time estimation parameters\non your recorded tracks.
+tip.downloadsrtm=You can speed this up by calling\nEn ligne -> T\u00e9l\u00e9charger les donn\u00e9es SRTM\nto save the data in your map cache.
+tip.usesrtmfor3d=This track doesn't have altitudes.\nYou can use the SRTM functions to get approximate\naltitudes for the 3d view.
 tip.manuallycorrelateone=En corr\u00e9lant manuellement au moins une photo, le d\u00e9calage de temps peut \u00eatre calcul\u00e9 pour vous.
 
 # Buttons
 tip.manuallycorrelateone=En corr\u00e9lant manuellement au moins une photo, le d\u00e9calage de temps peut \u00eatre calcul\u00e9 pour vous.
 
 # Buttons
@@ -576,6 +614,7 @@ button.yes=Oui
 button.no=Non
 button.yestoall=Oui pour tous
 button.notoall=Non pour tous
 button.no=Non
 button.yestoall=Oui pour tous
 button.notoall=Non pour tous
+button.always=Oui, toujours
 button.select=S\u00e9lectionner
 button.selectall=Tout s\u00e9lectionner
 button.selectnone=Ne rien s\u00e9lectionner
 button.select=S\u00e9lectionner
 button.selectall=Tout s\u00e9lectionner
 button.selectnone=Ne rien s\u00e9lectionner
@@ -608,6 +647,7 @@ filetype.audio=Fichiers MP3, OGG, WAV
 display.nodata=Pas de donn\u00e9es charg\u00e9es
 display.noaltitudes=La trace ne comporte pas d'information d'altitude
 display.notimestamps=La trace ne comporte pas d'information de temps
 display.nodata=Pas de donn\u00e9es charg\u00e9es
 display.noaltitudes=La trace ne comporte pas d'information d'altitude
 display.notimestamps=La trace ne comporte pas d'information de temps
+display.novalues=La trace ne comporte pas d'information pour ce champ
 details.trackdetails=D\u00e9tails de la trace
 details.notrack=Pas de trace charg\u00e9e
 details.track.points=Points
 details.trackdetails=D\u00e9tails de la trace
 details.notrack=Pas de trace charg\u00e9e
 details.track.points=Points
@@ -697,6 +737,10 @@ units.degminsec=Deg-min-sec
 units.degmin=Deg-min
 units.deg=Degr\u00e9s
 units.iso8601=ISO 8601
 units.degmin=Deg-min
 units.deg=Degr\u00e9s
 units.iso8601=ISO 8601
+units.degreescelsius=Celsius
+units.degreescelsius.short=\u00b0C
+units.degreesfahrenheit=Fahrenheit
+units.degreesfahrenheit.short=\u00b0F
 
 # How to combine conditions, such as filters
 logic.and=et
 
 # How to combine conditions, such as filters
 logic.and=et
@@ -727,6 +771,8 @@ undo.deletemarked=effacer les points
 undo.insert=ins\u00e9rer les points
 undo.reverse=inverser l'\u00e9tendue
 undo.mergetracksegments=fusionner les segments de trace
 undo.insert=ins\u00e9rer les points
 undo.reverse=inverser l'\u00e9tendue
 undo.mergetracksegments=fusionner les segments de trace
+undo.splitsegments=s\u00e9parer les segments de trace
+undo.sewsegments=r\u00e9unir les segments de trace
 undo.addtimeoffset=ajouter d\u00e9calage d'heure
 undo.addaltitudeoffset=ajouter d\u00e9calage d'altitude
 undo.rearrangewaypoints=r\u00e9arranger les waypoints
 undo.addtimeoffset=ajouter d\u00e9calage d'heure
 undo.addaltitudeoffset=ajouter d\u00e9calage d'altitude
 undo.rearrangewaypoints=r\u00e9arranger les waypoints
@@ -786,3 +832,4 @@ error.cache.notthere=Le dossier du cache n'a pas \u00e9t\u00e9 trouv\u00e9
 error.cache.empty=Le dossier du cache est vide
 error.cache.cannotdelete=Effacement des dalles impossible
 error.interpolate.invalidparameter=Le nombre de points doit \u00eatre compris entre 1 et 1000
 error.cache.empty=Le dossier du cache est vide
 error.cache.cannotdelete=Effacement des dalles impossible
 error.interpolate.invalidparameter=Le nombre de points doit \u00eatre compris entre 1 et 1000
+error.tracksplit.nosplit=Impossible de s\u00e9parer les segments
index e0e6b1ded649a8704fd87541210d77388d1fe5ad..a1bf2ec6677d5fbc4471922a39a6dd0426cd4ba0 100644 (file)
@@ -358,7 +358,6 @@ dialog.addmapsource.sourcename=Forr\u00e1s neve
 dialog.addmapsource.layer1url=Els\u0151 r\u00e9teg URL-je
 dialog.addmapsource.layer2url=Opcion\u00e1lis m\u00e1sodik r\u00e9teg URL-je
 dialog.addmapsource.maxzoom=Maxim\u00e1lis nagy\u00edt\u00e1si szint
 dialog.addmapsource.layer1url=Els\u0151 r\u00e9teg URL-je
 dialog.addmapsource.layer2url=Opcion\u00e1lis m\u00e1sodik r\u00e9teg URL-je
 dialog.addmapsource.maxzoom=Maxim\u00e1lis nagy\u00edt\u00e1si szint
-dialog.addmapsource.cloudstyle=St\u00edlus sz\u00e1ma
 dialog.addmapsource.noname=N\u00e9vtelen
 dialog.gpsies.column.name=Nyomvonal neve
 dialog.gpsies.column.length=Hossz
 dialog.addmapsource.noname=N\u00e9vtelen
 dialog.gpsies.column.name=Nyomvonal neve
 dialog.gpsies.column.length=Hossz
@@ -601,6 +600,7 @@ confirm.rotatephoto=f\u00e9nyk\u00e9p elforgatva
 confirm.running=Futtat\u00e1s...
 confirm.lookupsrtm=%d magass\u00e1gi \u00e9rt\u00e9k tal\u00e1lhat\u00f3
 confirm.downloadsrtm=%d f\u00e1jl let\u00f6lt\u00e9se gyors\u00edt\u00f3t\u00e1rba
 confirm.running=Futtat\u00e1s...
 confirm.lookupsrtm=%d magass\u00e1gi \u00e9rt\u00e9k tal\u00e1lhat\u00f3
 confirm.downloadsrtm=%d f\u00e1jl let\u00f6lt\u00e9se gyors\u00edt\u00f3t\u00e1rba
+confirm.downloadsrtm.1=%d f\u00e1jl let\u00f6lt\u00e9se gyors\u00edt\u00f3t\u00e1rba
 confirm.downloadsrtm.none=Nem kellett f\u00e1jlokat let\u00f6lteni, m\u00e1r gyors\u00edt\u00f3t\u00e1rban voltak.
 confirm.deletefieldvalues=Mez\u0151 \u00e9rt\u00e9kei t\u00f6r\u00f6lve
 confirm.audioload=Hangf\u00e1jl hozz\u00e1adva
 confirm.downloadsrtm.none=Nem kellett f\u00e1jlokat let\u00f6lteni, m\u00e1r gyors\u00edt\u00f3t\u00e1rban voltak.
 confirm.deletefieldvalues=Mez\u0151 \u00e9rt\u00e9kei t\u00f6r\u00f6lve
 confirm.audioload=Hangf\u00e1jl hozz\u00e1adva
index 63c70ea13ff24e7d392956bbfee8c5e0b540378c..14df8169a16abae54d82793a0e452175679537fc 100644 (file)
@@ -108,7 +108,7 @@ function.setmapbg=Configura sfondo mappa
 function.setpaths=Configura percorsi programmi
 function.splitsegments=Dividi traccia in segmenti
 function.sewsegments=Riorganizza segmenti insieme
 function.setpaths=Configura percorsi programmi
 function.splitsegments=Dividi traccia in segmenti
 function.sewsegments=Riorganizza segmenti insieme
-function.getgpsies=Ottieni traccie da Gpsies
+function.getgpsies=Ottieni tracce da Gpsies
 function.uploadgpsies=Carica traccia su Gpsies
 function.lookupsrtm=Ottieni quote da SRTM
 function.downloadsrtm=Scarica file da SRTM
 function.uploadgpsies=Carica traccia su Gpsies
 function.lookupsrtm=Ottieni quote da SRTM
 function.downloadsrtm=Scarica file da SRTM
@@ -358,7 +358,6 @@ dialog.addmapsource.sourcename=Nome della fonte
 dialog.addmapsource.layer1url=URL del primo layer
 dialog.addmapsource.layer2url=URL opzionale del secondo layer
 dialog.addmapsource.maxzoom=Massimo livello di zoom
 dialog.addmapsource.layer1url=URL del primo layer
 dialog.addmapsource.layer2url=URL opzionale del secondo layer
 dialog.addmapsource.maxzoom=Massimo livello di zoom
-dialog.addmapsource.cloudstyle=Stile numero
 dialog.addmapsource.noname=Senza nome
 dialog.gpsies.column.name=Nome traccia
 dialog.gpsies.column.length=Lunghezza
 dialog.addmapsource.noname=Senza nome
 dialog.gpsies.column.name=Nome traccia
 dialog.gpsies.column.length=Lunghezza
@@ -480,7 +479,7 @@ dialog.keys.keylist=<table><tr><td>Tasti freccia</td><td>Muovi mappa destra, sin
 dialog.keys.normalmodifier=Ctrl
 dialog.keys.macmodifier=Comando
 dialog.saveconfig.desc=Le configurazioni seguenti possono essere salvati in un file di configurazione:
 dialog.keys.normalmodifier=Ctrl
 dialog.keys.macmodifier=Comando
 dialog.saveconfig.desc=Le configurazioni seguenti possono essere salvati in un file di configurazione:
-dialog.saveconfig.prune.trackdirectory=Cartella traccie
+dialog.saveconfig.prune.trackdirectory=Cartella tracce
 dialog.saveconfig.prune.photodirectory=Cartella foto
 dialog.saveconfig.prune.languagecode=Codice lingua (IT)
 dialog.saveconfig.prune.languagefile=File lingua
 dialog.saveconfig.prune.photodirectory=Cartella foto
 dialog.saveconfig.prune.languagecode=Codice lingua (IT)
 dialog.saveconfig.prune.languagefile=File lingua
@@ -494,7 +493,6 @@ dialog.saveconfig.prune.mapsource=Selezionale la fonte delle mappe
 dialog.saveconfig.prune.mapsourcelist=Fonte delle mappe
 dialog.saveconfig.prune.diskcache=Cache delle mappe
 dialog.saveconfig.prune.kmzimagewidth=larghezza immagine KMZ
 dialog.saveconfig.prune.mapsourcelist=Fonte delle mappe
 dialog.saveconfig.prune.diskcache=Cache delle mappe
 dialog.saveconfig.prune.kmzimagewidth=larghezza immagine KMZ
-dialog.saveconfig.prune.kmzimageheight=altezza immagine KMZ
 dialog.saveconfig.prune.colourscheme=Schema colori
 dialog.saveconfig.prune.linewidth=Spessore linea
 dialog.saveconfig.prune.kmltrackcolour=Colore della traccia KML
 dialog.saveconfig.prune.colourscheme=Schema colori
 dialog.saveconfig.prune.linewidth=Spessore linea
 dialog.saveconfig.prune.kmltrackcolour=Colore della traccia KML
@@ -562,6 +560,10 @@ dialog.weather.day.thursday=Gioved\u00ec
 dialog.weather.day.friday=Venerd\u00ec
 dialog.weather.day.saturday=Sabato
 dialog.weather.day.sunday=Domenica
 dialog.weather.day.friday=Venerd\u00ec
 dialog.weather.day.saturday=Sabato
 dialog.weather.day.sunday=Domenica
+dialog.weather.wind=Vento
+dialog.weather.temp=Temp
+dialog.weather.humidity=Umidit\u00e0
+dialog.weather.creditnotice=Queste informazioni sono rese disponibili da openweathermap.org. Il loro sito web contiene ulteriori dettagli.
 
 # 3d window
 dialog.3d.title=Visione GpsPrune in 3D
 
 # 3d window
 dialog.3d.title=Visione GpsPrune in 3D
@@ -580,6 +582,8 @@ confirm.addtimeoffset=Scarto temporale aggiunto
 confirm.addaltitudeoffset=Scarto altitudine aggiunto
 confirm.rearrangewaypoints=Waypoint riorganizzati
 confirm.rearrangephotos=Foto riorganizzate
 confirm.addaltitudeoffset=Scarto altitudine aggiunto
 confirm.rearrangewaypoints=Waypoint riorganizzati
 confirm.rearrangephotos=Foto riorganizzate
+confirm.splitsegments=%d segmenti sono stati suddivisi
+confirm.sewsegments=%d segmenti sono stati raggruppati
 confirm.cutandmove=Selezione spostata
 confirm.interpolate=Aggiungi punto
 confirm.convertnamestotimes=Nome del waypoint convertito
 confirm.cutandmove=Selezione spostata
 confirm.interpolate=Aggiungi punto
 confirm.convertnamestotimes=Nome del waypoint convertito
@@ -598,6 +602,9 @@ confirm.createpoint=punto creato
 confirm.rotatephoto=foto ruotata
 confirm.running=Operazione in corso...
 confirm.lookupsrtm=Trovato %d valori di quota
 confirm.rotatephoto=foto ruotata
 confirm.running=Operazione in corso...
 confirm.lookupsrtm=Trovato %d valori di quota
+confirm.downloadsrtm=Scarica %d file nella cache
+confirm.downloadsrtm.1=Scarica %d file nella cache
+confirm.downloadsrtm.none=Nessun file scaricato, erano gi\u00e0 presenti nella cache
 confirm.deletefieldvalues=Valori del campo cancellati
 confirm.audioload=Ripresa audio aggiunta
 confirm.correlateaudios.single=la ripresa audio era correlata
 confirm.deletefieldvalues=Valori del campo cancellati
 confirm.audioload=Ripresa audio aggiunta
 confirm.correlateaudios.single=la ripresa audio era correlata
@@ -605,6 +612,10 @@ confirm.correlateaudios.multi=le riprese audio erano correlate
 
 # Tips
 tip.title=Consiglio
 
 # Tips
 tip.title=Consiglio
+tip.useamapcache=Usando una cache della mappa (Preferenze -> Salva mappe su disco)\npuoi accelerare la visualizzazione e ridurre il traffico.
+tip.learntimeparams=I risultati saranno pi\u00f9 precisi usando\nTraccia -> Apprendi parametri di stima\ncon le tue tracce.
+tip.downloadsrtm=Puoi accelerare questa funzione usando\nOnline -> Scarica file da SRTM\nper salvare i dati nella cache.
+tip.usesrtmfor3d=La traccia non include informazioni sull'altitudine.\nPuoi utilizzare la funzione SRTM per ottenere le altitudini\nper la visione 3D.
 tip.manuallycorrelateone=Con il collegamento manuale di almeno una foto, lo scarto di orario viene calcolato per te
 
 # Buttons
 tip.manuallycorrelateone=Con il collegamento manuale di almeno una foto, lo scarto di orario viene calcolato per te
 
 # Buttons
@@ -713,7 +724,6 @@ fieldname.newsegment=Segmento
 fieldname.custom=Custom
 fieldname.prefix=Campo
 fieldname.distance=Distanza
 fieldname.custom=Custom
 fieldname.prefix=Campo
 fieldname.distance=Distanza
-fieldname.movingdistance=Distanza in movimento
 fieldname.duration=Durata
 fieldname.speed=Velocit\u00e0
 fieldname.verticalspeed=Velocit\u00e0 verticale
 fieldname.duration=Durata
 fieldname.speed=Velocit\u00e0
 fieldname.verticalspeed=Velocit\u00e0 verticale
@@ -844,3 +854,6 @@ error.cache.empty=Directory del cache di tasselli \u00e8 vuoto
 error.cache.cannotdelete=Impossibile cancellare tasselli
 error.interpolate.invalidparameter=Il numero di punti deve essere tra 1 e 1000
 error.learnestimationparams.failed=Non \u00e8 possibile apprendere i parametri da questa traccia.\nProva a caricare pi\u00f9 tracce.
 error.cache.cannotdelete=Impossibile cancellare tasselli
 error.interpolate.invalidparameter=Il numero di punti deve essere tra 1 e 1000
 error.learnestimationparams.failed=Non \u00e8 possibile apprendere i parametri da questa traccia.\nProva a caricare pi\u00f9 tracce.
+error.tracksplit.nosplit=La traccia non pu\u00f2 essere divisa
+error.downloadsrtm.nocache=Non \u00e8 stato possibile salvare i file.\nControlla la cache del disco.
+error.sewsegments.nothingdone=Non \u00e8 stato possibile riorganizzare nessun segmento.\nCi sono %d segmenti nella traccia.
index 5e09c49c5056b759799757b9c0d7c257abf3d878..e581c18b51e2fd2246225ba3248126b908424a95 100644 (file)
@@ -225,7 +225,6 @@ dialog.undo.none.text=\u30a2\u30f3\u30c9\u30a5\u3067\u304d\u308b\u4f5c\u696d\u75
 dialog.clearundo.title=\u30a2\u30f3\u30c9\u30a5\u30ea\u30b9\u30c8\u3092\u7a7a\u306b\u3059\u308b
 dialog.clearundo.text=\u672c\u5f53\u306b\u30a2\u30f3\u30c9\u30a5\u30ea\u30b9\u30c8\u3092\u7a7a\u306b\u3057\u307e\u3059\u304b?\n\u5168\u3066\u306e\u30a2\u30f3\u30c9\u30a5\u60c5\u5831\u304c\u5931\u308f\u308c\u307e\u3059\u3002
 dialog.pointedit.title=\u70b9\u3092\u7de8\u96c6
 dialog.clearundo.title=\u30a2\u30f3\u30c9\u30a5\u30ea\u30b9\u30c8\u3092\u7a7a\u306b\u3059\u308b
 dialog.clearundo.text=\u672c\u5f53\u306b\u30a2\u30f3\u30c9\u30a5\u30ea\u30b9\u30c8\u3092\u7a7a\u306b\u3057\u307e\u3059\u304b?\n\u5168\u3066\u306e\u30a2\u30f3\u30c9\u30a5\u60c5\u5831\u304c\u5931\u308f\u308c\u307e\u3059\u3002
 dialog.pointedit.title=\u70b9\u3092\u7de8\u96c6
-dialog.pointedit.text=\u7de8\u96c6\u3059\u308b\u30d5\u30a3\u30fc\u30eb\u30c9\u3092\u9078\u629e\u3057\u3001'\u7de8\u96c6' \u30dc\u30bf\u30f3\u3067\u5024\u3092\u7de8\u96c6\u3057\u3066\u304f\u3060\u3055\u3044\u3002
 dialog.pointedit.table.field=\u30d5\u30a3\u30fc\u30eb\u30c9
 dialog.pointedit.table.value=\u503c
 dialog.pointnameedit.name=\u30a6\u30a7\u30a4\u30dd\u30a4\u30f3\u30c8\u540d
 dialog.pointedit.table.field=\u30d5\u30a3\u30fc\u30eb\u30c9
 dialog.pointedit.table.value=\u503c
 dialog.pointnameedit.name=\u30a6\u30a7\u30a4\u30dd\u30a4\u30f3\u30c8\u540d
@@ -270,7 +269,6 @@ dialog.fullrangedetails.intro=\u9078\u629e\u7bc4\u56f2\u306b\u306f\u8a73\u7d30\u
 dialog.addmapsource.title=\u65b0\u3057\u3044\u30de\u30c3\u30d7\u30fb\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0
 dialog.addmapsource.sourcename=\u30bd\u30fc\u30b9\u306e\u540d\u524d
 dialog.addmapsource.maxzoom=\u6700\u5927\u30ba\u30fc\u30e0\u30ec\u30d9\u30eb
 dialog.addmapsource.title=\u65b0\u3057\u3044\u30de\u30c3\u30d7\u30fb\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0
 dialog.addmapsource.sourcename=\u30bd\u30fc\u30b9\u306e\u540d\u524d
 dialog.addmapsource.maxzoom=\u6700\u5927\u30ba\u30fc\u30e0\u30ec\u30d9\u30eb
-dialog.addmapsource.cloudstyle=\u30b9\u30bf\u30a4\u30eb\u756a\u53f7
 dialog.addmapsource.noname=\u540d\u524d\u306a\u3057
 dialog.gpsies.column.name=\u30c8\u30e9\u30c3\u30af\u540d
 dialog.gpsies.column.length=\u9577\u3055
 dialog.addmapsource.noname=\u540d\u524d\u306a\u3057
 dialog.gpsies.column.name=\u30c8\u30e9\u30c3\u30af\u540d
 dialog.gpsies.column.length=\u9577\u3055
@@ -391,7 +389,6 @@ dialog.saveconfig.prune.mapsource=\u30de\u30c3\u30d7\u30fb\u30bd\u30fc\u30b9\u30
 dialog.saveconfig.prune.mapsourcelist=\u30de\u30c3\u30d7\u30fb\u30bd\u30fc\u30b9
 dialog.saveconfig.prune.diskcache=\u30de\u30c3\u30d7\u306e\u30ad\u30e3\u30c3\u30b7\u30e5
 dialog.saveconfig.prune.kmzimagewidth=KML \u753b\u50cf\u5e45
 dialog.saveconfig.prune.mapsourcelist=\u30de\u30c3\u30d7\u30fb\u30bd\u30fc\u30b9
 dialog.saveconfig.prune.diskcache=\u30de\u30c3\u30d7\u306e\u30ad\u30e3\u30c3\u30b7\u30e5
 dialog.saveconfig.prune.kmzimagewidth=KML \u753b\u50cf\u5e45
-dialog.saveconfig.prune.kmzimageheight=KML \u753b\u50cf\u9ad8
 dialog.saveconfig.prune.colourscheme=\u8272\u306e\u30b9\u30ad\u30fc\u30e0
 dialog.saveconfig.prune.linewidth=\u7dda\u306e\u5e45
 dialog.saveconfig.prune.kmltrackcolour=KML \u30c8\u30e9\u30c3\u30af\u306e\u8272
 dialog.saveconfig.prune.colourscheme=\u8272\u306e\u30b9\u30ad\u30fc\u30e0
 dialog.saveconfig.prune.linewidth=\u7dda\u306e\u5e45
 dialog.saveconfig.prune.kmltrackcolour=KML \u30c8\u30e9\u30c3\u30af\u306e\u8272
index 583c2c5d7e57c3a81ae973af3c1218be112dda0d..b14b0a5b6fa09761f499602e84e8d4e2e47455cd 100644 (file)
@@ -219,7 +219,6 @@ dialog.undo.none.text=\ub418\ub3cc\ub9b4 \uc791\uc5c5\uc774 \uc5c6\uc5b4\uc694!
 dialog.clearundo.title=\ub418\ub3cc\ub9ac\uae30 \ubaa9\ub85d \uc9c0\uc6b0\uae30
 dialog.clearundo.text=\uc815\ub9d0\ub85c \ub418\ub3cc\ub9ac\uae30 \ubaa9\ub85d \uc9c0\uc6b0\uc2e4\uac74\uac00\uc694? /n \ubaa8\ub4e0 \ub418\ub3cc\ub9ac\uae30 \uc815\ubcf4\uac00 \uc5c6\uc5b4\uc9c4\ub2e4\uad6c\uc694!
 dialog.pointedit.title=\uc9c0\uc810 \uc218\uc815\ud558\uae30
 dialog.clearundo.title=\ub418\ub3cc\ub9ac\uae30 \ubaa9\ub85d \uc9c0\uc6b0\uae30
 dialog.clearundo.text=\uc815\ub9d0\ub85c \ub418\ub3cc\ub9ac\uae30 \ubaa9\ub85d \uc9c0\uc6b0\uc2e4\uac74\uac00\uc694? /n \ubaa8\ub4e0 \ub418\ub3cc\ub9ac\uae30 \uc815\ubcf4\uac00 \uc5c6\uc5b4\uc9c4\ub2e4\uad6c\uc694!
 dialog.pointedit.title=\uc9c0\uc810 \uc218\uc815\ud558\uae30
-dialog.pointedit.text=\uc218\uc815\ud560 \ud544\ub4dc\ub97c \uc120\ud0dd\ud558\uc2dc\uace0, \uc218\uc815\ud558\uae30 \ubc84\ud2bc\uc744 \uc0ac\uc6a9\ud558\uc138\uc694.
 dialog.pointedit.table.field=\ud544\ub4dc
 dialog.pointedit.table.value=\uac12
 dialog.pointnameedit.name=\uacbd\uc720\uc9c0 \uc774\ub984
 dialog.pointedit.table.field=\ud544\ub4dc
 dialog.pointedit.table.value=\uac12
 dialog.pointnameedit.name=\uacbd\uc720\uc9c0 \uc774\ub984
@@ -267,7 +266,6 @@ dialog.addmapsource.sourcename=\uc18c\uc2a4 \uc774\ub984
 dialog.addmapsource.layer1url=\uccab \ub808\uc774\uc5b4\uc758 URL
 dialog.addmapsource.layer2url=\ub450\ubc88\uc9f8 \ub808\uc774\uc5b4\uc758 URL
 dialog.addmapsource.maxzoom=\ucd5c\uace0 \ud655\ub300
 dialog.addmapsource.layer1url=\uccab \ub808\uc774\uc5b4\uc758 URL
 dialog.addmapsource.layer2url=\ub450\ubc88\uc9f8 \ub808\uc774\uc5b4\uc758 URL
 dialog.addmapsource.maxzoom=\ucd5c\uace0 \ud655\ub300
-dialog.addmapsource.cloudstyle=\uc2a4\ud0c0\uc77c \uc218
 dialog.addmapsource.noname=\uc774\ub984 \uc5c6\uc74c
 dialog.gpsies.column.name=\ud2b8\ub809 \uc774\ub984
 dialog.gpsies.column.length=\uae38\uc774
 dialog.addmapsource.noname=\uc774\ub984 \uc5c6\uc74c
 dialog.gpsies.column.name=\ud2b8\ub809 \uc774\ub984
 dialog.gpsies.column.length=\uae38\uc774
@@ -398,7 +396,6 @@ dialog.saveconfig.prune.mapsource=\uc120\ud0dd\ub41c \uc9c0\ub3c4 \uc704\uce58
 dialog.saveconfig.prune.mapsourcelist=\uc9c0\ub3c4 \uc18c\uc2a4
 dialog.saveconfig.prune.diskcache=\uc9c0\ub3c4 \uce90\uc2dc
 dialog.saveconfig.prune.kmzimagewidth=KMZ \uc774\ubbf8\uc9c0 \ub113\uc774
 dialog.saveconfig.prune.mapsourcelist=\uc9c0\ub3c4 \uc18c\uc2a4
 dialog.saveconfig.prune.diskcache=\uc9c0\ub3c4 \uce90\uc2dc
 dialog.saveconfig.prune.kmzimagewidth=KMZ \uc774\ubbf8\uc9c0 \ub113\uc774
-dialog.saveconfig.prune.kmzimageheight=KMZ \uc774\ubbf8\uc9c0 \ub192\uc774
 dialog.saveconfig.prune.colourscheme=\uc0c9 \uad6c\uc131
 dialog.saveconfig.prune.linewidth=\ud2b8\ub799\uc120 \ub450\uaed8
 dialog.saveconfig.prune.kmltrackcolour=KML \ud2b8\ub799 \uc0c9
 dialog.saveconfig.prune.colourscheme=\uc0c9 \uad6c\uc131
 dialog.saveconfig.prune.linewidth=\ud2b8\ub799\uc120 \ub450\uaed8
 dialog.saveconfig.prune.kmltrackcolour=KML \ud2b8\ub799 \uc0c9
index 8c0e8a9cd8096264fd06f47ae5787bdf6ad9ac14..a077bc95e45a2ed9f476aa697d72712fb5f83b35 100644 (file)
@@ -358,7 +358,6 @@ dialog.addmapsource.sourcename=Naam van de bron
 dialog.addmapsource.layer1url=URL van de eerste laag
 dialog.addmapsource.layer2url=URL van de tweede laag (optioneel)
 dialog.addmapsource.maxzoom=Maximaal zoom-niveau
 dialog.addmapsource.layer1url=URL van de eerste laag
 dialog.addmapsource.layer2url=URL van de tweede laag (optioneel)
 dialog.addmapsource.maxzoom=Maximaal zoom-niveau
-dialog.addmapsource.cloudstyle=Stijl nummer
 dialog.addmapsource.noname=Onbenoemd
 dialog.gpsies.column.name=Routenaam
 dialog.gpsies.column.length=Lengte
 dialog.addmapsource.noname=Onbenoemd
 dialog.gpsies.column.name=Routenaam
 dialog.gpsies.column.length=Lengte
@@ -561,6 +560,7 @@ dialog.weather.day.thursday=Donderdag
 dialog.weather.day.friday=Vrijdag
 dialog.weather.day.saturday=Zaterdag
 dialog.weather.day.sunday=Zondag
 dialog.weather.day.friday=Vrijdag
 dialog.weather.day.saturday=Zaterdag
 dialog.weather.day.sunday=Zondag
+dialog.weather.humidity=Luchtvocht.
 dialog.weather.creditnotice=Deze gegevens worden beschikbaar gesteld door openweathermap.org. Hun website heeft meer details.
 
 # 3d window
 dialog.weather.creditnotice=Deze gegevens worden beschikbaar gesteld door openweathermap.org. Hun website heeft meer details.
 
 # 3d window
@@ -601,6 +601,7 @@ confirm.rotatephoto=foto geroteerd
 confirm.running=Bezig...
 confirm.lookupsrtm=Gevonden %d hoote waarden
 confirm.downloadsrtm=Er zijn %d bestanden gedownload nar de cache
 confirm.running=Bezig...
 confirm.lookupsrtm=Gevonden %d hoote waarden
 confirm.downloadsrtm=Er zijn %d bestanden gedownload nar de cache
+confirm.downloadsrtm.1=Er zijn %d bestanden gedownload nar de cache
 confirm.downloadsrtm.none=Geen bestanden gedownload, waren al aanwezig in de cache.
 confirm.deletefieldvalues=Veldwaarden gewist
 confirm.audioload=Audiobestanden toegevoegd
 confirm.downloadsrtm.none=Geen bestanden gedownload, waren al aanwezig in de cache.
 confirm.deletefieldvalues=Veldwaarden gewist
 confirm.audioload=Audiobestanden toegevoegd
index 212eb695b30b10c751851f1bf6fd3ef77808a2b9..80a67c149e994878a750ba8777ab9090a52a3768 100644 (file)
@@ -352,7 +352,6 @@ dialog.addmapsource.sourcename=Nazwa dostawcy
 dialog.addmapsource.layer1url=URL pierwszej warstwy
 dialog.addmapsource.layer2url=Opcjonalny URL drugiej warstwy
 dialog.addmapsource.maxzoom=Maksymalny poziom zbli\u017cenia
 dialog.addmapsource.layer1url=URL pierwszej warstwy
 dialog.addmapsource.layer2url=Opcjonalny URL drugiej warstwy
 dialog.addmapsource.maxzoom=Maksymalny poziom zbli\u017cenia
-dialog.addmapsource.cloudstyle=Numer stylu
 dialog.addmapsource.noname=Nienazwane
 dialog.gpsies.column.name=Nazwa \u015bcie\u017cki
 dialog.gpsies.column.length=D\u0142ugo\u015b\u0107
 dialog.addmapsource.noname=Nienazwane
 dialog.gpsies.column.name=Nazwa \u015bcie\u017cki
 dialog.gpsies.column.length=D\u0142ugo\u015b\u0107
index f70a01e9497d2d2624770e77f2192f3f135ddc98..85870ad0faf16167cd24df9298d57b083c37187d 100644 (file)
@@ -18,8 +18,8 @@ menu.track.rearrange.start=Tudo para o in\u00edcio do arquivo
 menu.track.rearrange.end=Tudo para o fim do arquivo
 menu.track.rearrange.nearest=Cada um para o ponto da rota mais pr\u00f3ximo
 menu.range=Intervalo
 menu.track.rearrange.end=Tudo para o fim do arquivo
 menu.track.rearrange.nearest=Cada um para o ponto da rota mais pr\u00f3ximo
 menu.range=Intervalo
-menu.range.all=Selectionar tudo
-menu.range.none=N\u00e3o selecionar nenhuns
+menu.range.all=Selecionar tudo
+menu.range.none=Desmarcar todas as sele\u00e7\u00f5es
 menu.range.start=Definir in\u00edcio do intervalo
 menu.range.end=Definir fim do intervalo
 menu.range.average=Sele\u00e7\u00e3o m\u00e9dia
 menu.range.start=Definir in\u00edcio do intervalo
 menu.range.end=Definir fim do intervalo
 menu.range.average=Sele\u00e7\u00e3o m\u00e9dia
@@ -36,7 +36,7 @@ menu.view=Exibir
 menu.view.showsidebars=Mostrar barras laterais
 menu.view.browser=Mapear no navegador
 menu.view.browser.google=Mapas do Google
 menu.view.showsidebars=Mostrar barras laterais
 menu.view.browser=Mapear no navegador
 menu.view.browser.google=Mapas do Google
-menu.view.browser.openstreetmap=Mapas do Openstreetmap
+menu.view.browser.openstreetmap=Mapas do OpenStreetMap
 menu.view.browser.mapquest=Mapas do Mapquest
 menu.view.browser.yahoo=Mapas do Yahoo
 menu.view.browser.bing=Mapas do Bing
 menu.view.browser.mapquest=Mapas do Mapquest
 menu.view.browser.yahoo=Mapas do Yahoo
 menu.view.browser.bing=Mapas do Bing
@@ -112,8 +112,8 @@ function.getgpsies=Obter rotas Gpsies
 function.uploadgpsies=Enviar rotas para o Gpsies
 function.lookupsrtm=Obter altitudes a partir do SRTM
 function.downloadsrtm=Baixar arquivos SRTM
 function.uploadgpsies=Enviar rotas para o Gpsies
 function.lookupsrtm=Obter altitudes a partir do SRTM
 function.downloadsrtm=Baixar arquivos SRTM
-function.getwikipedia=Obter artigos da Wikipedia das redondezas
-function.searchwikipedianames=Procurar na Wikipedia por nome
+function.getwikipedia=Obter artigos da Wikip\u00e9dia das redondezas
+function.searchwikipedianames=Procurar na Wikip\u00e9dia por nome
 function.downloadosm=Baixar dados OSM para a \u00e1rea
 function.duplicatepoint=Duplicar ponto
 function.setcolours=Definir cores
 function.downloadosm=Baixar dados OSM para a \u00e1rea
 function.duplicatepoint=Duplicar ponto
 function.setcolours=Definir cores
@@ -127,7 +127,7 @@ function.rearrangephotos=Rearrumar fotos
 function.rotatephotoleft=Roda foto \u00e0 esquerda
 function.rotatephotoright=Roda foto \u00e0 direita
 function.photopopup=Mostrar janela da foto
 function.rotatephotoleft=Roda foto \u00e0 esquerda
 function.rotatephotoright=Roda foto \u00e0 direita
 function.photopopup=Mostrar janela da foto
-function.ignoreexifthumb=Ignorar miniatura do exif
+function.ignoreexifthumb=Ignorar miniatura do Exif
 function.loadaudio=Adicionar arquivos de \u00e1udio
 function.removeaudio=Remover arquivo de \u00e1udio
 function.correlateaudios=Correlacionar \u00e1udios
 function.loadaudio=Adicionar arquivos de \u00e1udio
 function.removeaudio=Remover arquivo de \u00e1udio
 function.correlateaudios=Correlacionar \u00e1udios
@@ -144,7 +144,7 @@ function.getweatherforecast=Baixar a previs\u00e3o do tempo para a \u00e1rea atu
 
 # Dialogs
 dialog.exit.confirm.title=Sair do GpsPrune
 
 # Dialogs
 dialog.exit.confirm.title=Sair do GpsPrune
-dialog.exit.confirm.text=Seus dados n\u00e3o foram salvos. Voc\u00ea tem certeza que deseja sair?
+dialog.exit.confirm.text=Seus dados n\u00e3o foram salvos. Voc\u00ea tem certeza de que deseja sair?
 dialog.openappend.title=Adicionar aos dados existentes
 dialog.openappend.text=Adicionar estes dados aos dados j\u00e1 carregados?
 dialog.deletepoint.title=Remover Ponto
 dialog.openappend.title=Adicionar aos dados existentes
 dialog.openappend.text=Adicionar estes dados aos dados j\u00e1 carregados?
 dialog.deletepoint.title=Remover Ponto
@@ -222,12 +222,12 @@ dialog.save.coordinateunits=Unidades das coordenadas
 dialog.save.altitudeunits=Unidades da altitude
 dialog.save.timestampformat=Formato da data-hora
 dialog.save.overwrite.title=Arquivo j\u00e1 existe
 dialog.save.altitudeunits=Unidades da altitude
 dialog.save.timestampformat=Formato da data-hora
 dialog.save.overwrite.title=Arquivo j\u00e1 existe
-dialog.save.overwrite.text=Este arquivo j\u00e1 existe. Voc\u00ea tem certeza que deseja sobrescrev\u00ea-lo?
+dialog.save.overwrite.text=Este arquivo j\u00e1 existe. Voc\u00ea tem certeza de que deseja sobrescrev\u00ea-lo?
 dialog.save.notypesselected=Nenhum tipo de ponto foi selecionado
 dialog.exportkml.text=T\u00edtulo para os dados
 dialog.exportkml.altitude=Incluir altitudes (para avia\u00e7\u00e3o)
 dialog.save.notypesselected=Nenhum tipo de ponto foi selecionado
 dialog.exportkml.text=T\u00edtulo para os dados
 dialog.exportkml.altitude=Incluir altitudes (para avia\u00e7\u00e3o)
-dialog.exportkml.kmz=Comprimir para criar arquivo kmz
-dialog.exportkml.exportimages=Exportar miniaturas de imagem para o kmz
+dialog.exportkml.kmz=Comprimir para criar arquivo KMZ
+dialog.exportkml.exportimages=Exportar miniaturas de imagem para o KMZ
 dialog.exportkml.imagesize=Tamanho da imagem
 dialog.exportkml.trackcolour=Cor da rota
 dialog.exportkml.standardkml=KML plano
 dialog.exportkml.imagesize=Tamanho da imagem
 dialog.exportkml.trackcolour=Cor da rota
 dialog.exportkml.standardkml=KML plano
@@ -247,7 +247,7 @@ dialog.exportpov.cameraz=Z da C\u00e2mera
 dialog.exportpov.modelstyle=Estilo do modelo
 dialog.exportpov.ballsandsticks=Bolas e galhos
 dialog.exportpov.tubesandwalls=Tubos e muros
 dialog.exportpov.modelstyle=Estilo do modelo
 dialog.exportpov.ballsandsticks=Bolas e galhos
 dialog.exportpov.tubesandwalls=Tubos e muros
-dialog.3d.warningtracksize=Esta rota possui um grande n\u00famero de pontos, os quais o Java3D n\u00e3o ser\u00e1 capaz de exibir.\n Voc\u00ea tem certeza que deseja continuar?
+dialog.3d.warningtracksize=Esta rota possui um grande n\u00famero de pontos, os quais o Java3D n\u00e3o ser\u00e1 capaz de exibir.\n Voc\u00ea tem certeza de que deseja continuar?
 dialog.3d.useterrain=Mostrar terreno
 dialog.3d.terraingridsize=Tamanho da grade
 dialog.exportpov.baseimage=Imagem base
 dialog.3d.useterrain=Mostrar terreno
 dialog.3d.terraingridsize=Tamanho da grade
 dialog.exportpov.baseimage=Imagem base
@@ -274,9 +274,9 @@ dialog.pointtype.photo=Pontos de foto
 dialog.pointtype.audio=Pontos de \u00e1udio
 dialog.pointtype.selection=Apenas sele\u00e7\u00e3o
 dialog.confirmreversetrack.title=Confirmar invers\u00e3o
 dialog.pointtype.audio=Pontos de \u00e1udio
 dialog.pointtype.selection=Apenas sele\u00e7\u00e3o
 dialog.confirmreversetrack.title=Confirmar invers\u00e3o
-dialog.confirmreversetrack.text=Esta rota possui informa\u00e7\u00f5es de data-hora, as quais estar\u00e3o fora de sequ\u00eancia ap\u00f3s a revers\u00e3o.\n Voc\u00ea tem certeza que deseja reverter esta se\u00e7\u00e3o?
+dialog.confirmreversetrack.text=Esta rota possui informa\u00e7\u00f5es de data-hora, as quais estar\u00e3o fora de sequ\u00eancia ap\u00f3s a revers\u00e3o.\n Voc\u00ea tem certeza de que deseja reverter esta se\u00e7\u00e3o?
 dialog.confirmcutandmove.title=Confirmar cortar e mover
 dialog.confirmcutandmove.title=Confirmar cortar e mover
-dialog.confirmcutandmove.text=A rota cont\u00e9m informa\u00e7\u00f5es de data-hora, as quais estar\u00e3o fora de sequ\u00eancia ap\u00f3s o movimento.\n Voc\u00ea tem certeza que deseja mover esta se\u00e7\u00e3o?
+dialog.confirmcutandmove.text=A rota cont\u00e9m informa\u00e7\u00f5es de data-hora, as quais estar\u00e3o fora de sequ\u00eancia ap\u00f3s o movimento.\n Voc\u00ea tem certeza de que deseja mover esta se\u00e7\u00e3o?
 dialog.interpolate.parameter.text=N\u00famero de pontos para inserir entre os pontos selecionados
 dialog.interpolate.betweenwaypoints=Interpolar entre os pontos do caminho?
 dialog.undo.title=A\u00e7\u00e3o(\u00f5es) de desfazer
 dialog.interpolate.parameter.text=N\u00famero de pontos para inserir entre os pontos selecionados
 dialog.interpolate.betweenwaypoints=Interpolar entre os pontos do caminho?
 dialog.undo.title=A\u00e7\u00e3o(\u00f5es) de desfazer
@@ -284,7 +284,7 @@ dialog.undo.pretext=Por favor, selecione a a\u00e7\u00e3o(\u00f5es) a desfazer
 dialog.undo.none.title=N\u00e3o foi poss\u00edvel desfazer
 dialog.undo.none.text=Nenhuma opera\u00e7\u00e3o a desfazer!
 dialog.clearundo.title=Limpar lista de desfazer
 dialog.undo.none.title=N\u00e3o foi poss\u00edvel desfazer
 dialog.undo.none.text=Nenhuma opera\u00e7\u00e3o a desfazer!
 dialog.clearundo.title=Limpar lista de desfazer
-dialog.clearundo.text=Voc\u00ea tem certeza que deseja limpar a lista de desfazer?\n Todas as informa\u00e7\u00f5es para desfazer ser\u00e3o perdidas!
+dialog.clearundo.text=Voc\u00ea tem certeza de que deseja limpar a lista de desfazer?\n Todas as informa\u00e7\u00f5es para desfazer ser\u00e3o perdidas!
 dialog.pointedit.title=Editar ponto
 dialog.pointedit.intro=Selecionar cada campo para mudar o valor
 dialog.pointedit.table.field=Campo
 dialog.pointedit.title=Editar ponto
 dialog.pointedit.intro=Selecionar cada campo para mudar o valor
 dialog.pointedit.table.field=Campo
@@ -358,7 +358,6 @@ dialog.addmapsource.sourcename=Nome da fonte
 dialog.addmapsource.layer1url=URL da primeira camada
 dialog.addmapsource.layer2url=URL opcional da segunda camada
 dialog.addmapsource.maxzoom=N\u00edvel de amplia\u00e7\u00e3o m\u00e1ximo
 dialog.addmapsource.layer1url=URL da primeira camada
 dialog.addmapsource.layer2url=URL opcional da segunda camada
 dialog.addmapsource.maxzoom=N\u00edvel de amplia\u00e7\u00e3o m\u00e1ximo
-dialog.addmapsource.cloudstyle=N\u00famero do estilo
 dialog.addmapsource.noname=Sem nome
 dialog.gpsies.column.name=Nome da rota
 dialog.gpsies.column.length=Extens\u00e3o
 dialog.addmapsource.noname=Sem nome
 dialog.gpsies.column.name=Nome da rota
 dialog.gpsies.column.length=Extens\u00e3o
@@ -381,8 +380,8 @@ dialog.gpsies.activity.skating=Patina\u00e7\u00e3o
 dialog.wikipedia.column.name=Nome do artigo
 dialog.wikipedia.column.distance=Dist\u00e2ncia
 dialog.correlate.notimestamps=N\u00e3o existem data-hora nos dados dos pontos, assim n\u00e3o h\u00e1 nada para correlacionar com as fotos
 dialog.wikipedia.column.name=Nome do artigo
 dialog.wikipedia.column.distance=Dist\u00e2ncia
 dialog.correlate.notimestamps=N\u00e3o existem data-hora nos dados dos pontos, assim n\u00e3o h\u00e1 nada para correlacionar com as fotos
-dialog.correlate.nouncorrelatedphotos=Existem fotos n\u00e3o correlacionadas.\nVoc\u00ea tem certeza que deseja continuar?
-dialog.correlate.nouncorrelatedaudios=Existem \u00e1udios n\u00e3o correlacionados.\nVoc\u00ea tem certeza que deseja continuar?
+dialog.correlate.nouncorrelatedphotos=Existem fotos n\u00e3o correlacionadas.\nVoc\u00ea tem certeza de que deseja continuar?
+dialog.correlate.nouncorrelatedaudios=Existem \u00e1udios n\u00e3o correlacionados.\nVoc\u00ea tem certeza de que deseja continuar?
 dialog.correlate.photoselect.intro=Selecione uma destas fotos correlacionadas para usar como diferen\u00e7a de tempo
 dialog.correlate.select.photoname=Nome da foto
 dialog.correlate.select.timediff=Diferen\u00e7a de tempo
 dialog.correlate.photoselect.intro=Selecione uma destas fotos correlacionadas para usar como diferen\u00e7a de tempo
 dialog.correlate.select.photoname=Nome da foto
 dialog.correlate.select.timediff=Diferen\u00e7a de tempo
@@ -561,6 +560,9 @@ dialog.weather.day.thursday=Quinta
 dialog.weather.day.friday=Sexta
 dialog.weather.day.saturday=S\u00e1bado
 dialog.weather.day.sunday=Domingo
 dialog.weather.day.friday=Sexta
 dialog.weather.day.saturday=S\u00e1bado
 dialog.weather.day.sunday=Domingo
+dialog.weather.wind=Vento
+dialog.weather.temp=Temp
+dialog.weather.humidity=Umidade
 dialog.weather.creditnotice=Estes dados foram disponibilizados por openweathermap.org. A p\u00e1gina Web possui mais detalhes.
 
 # 3d window
 dialog.weather.creditnotice=Estes dados foram disponibilizados por openweathermap.org. A p\u00e1gina Web possui mais detalhes.
 
 # 3d window
@@ -601,6 +603,7 @@ confirm.rotatephoto=foto rotacionada
 confirm.running=Rodando...
 confirm.lookupsrtm=Encontrado %d valores de altitude
 confirm.downloadsrtm=%d arquivos baixados para a cache
 confirm.running=Rodando...
 confirm.lookupsrtm=Encontrado %d valores de altitude
 confirm.downloadsrtm=%d arquivos baixados para a cache
+confirm.downloadsrtm.1=%d arquivo baixados para a cache
 confirm.downloadsrtm.none=Nenhum arquivo baixado, pois j\u00e1 est\u00e3o na cache.
 confirm.deletefieldvalues=Valores do campo removidos
 confirm.audioload=Arquivos de \u00e1udio adicionados
 confirm.downloadsrtm.none=Nenhum arquivo baixado, pois j\u00e1 est\u00e3o na cache.
 confirm.deletefieldvalues=Valores do campo removidos
 confirm.audioload=Arquivos de \u00e1udio adicionados
index ce483bd554c74a1f629e57abace781711104787f..3481dba779666bd1f6f35496285ff2e3a40e6e0d 100644 (file)
@@ -7,6 +7,7 @@ menu.file.addphotos=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0444\u043
 menu.file.recentfiles=\u041f\u0440\u0438\u043d\u044f\u0442\u044b\u0435 \u0444\u0430\u0439\u043b\u044b
 menu.file.save=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043a\u0430\u043a \u0442\u0435\u043a\u0441\u0442
 menu.file.exit=\u0412\u044b\u0445\u043e\u0434
 menu.file.recentfiles=\u041f\u0440\u0438\u043d\u044f\u0442\u044b\u0435 \u0444\u0430\u0439\u043b\u044b
 menu.file.save=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043a\u0430\u043a \u0442\u0435\u043a\u0441\u0442
 menu.file.exit=\u0412\u044b\u0445\u043e\u0434
+menu.online=\u041e\u043d\u043b\u0430\u0439\u043d
 menu.track=\u0422\u0440\u0435\u043a
 menu.track.undo=\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c
 menu.track.clearundo=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439
 menu.track=\u0422\u0440\u0435\u043a
 menu.track.undo=\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c
 menu.track.clearundo=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439
@@ -57,6 +58,7 @@ menu.map.editmode=\u0420\u0435\u0436\u0438\u043c \u0440\u0435\u0434\u0430\u043a\
 
 # Alt keys for menus
 altkey.menu.file=F
 
 # Alt keys for menus
 altkey.menu.file=F
+altkey.menu.online=N
 altkey.menu.track=T
 altkey.menu.range=R
 altkey.menu.point=P
 altkey.menu.track=T
 altkey.menu.range=R
 altkey.menu.point=P
@@ -100,11 +102,16 @@ function.charts=\u0413\u0440\u0430\u0444\u0438\u043a\u0438
 function.show3d=3D-\u0432\u0438\u0434
 function.distances=\u0420\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u044f
 function.fullrangedetails=\u0414\u0435\u0442\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u043e \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u0443
 function.show3d=3D-\u0432\u0438\u0434
 function.distances=\u0420\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u044f
 function.fullrangedetails=\u0414\u0435\u0442\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u043e \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u0443
+function.estimatetime=\u041f\u0440\u043e\u0433\u043d\u043e\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0440\u0435\u043c\u044f
+function.learnestimationparams=\u0417\u0430\u043f\u043e\u043c\u043d\u0438\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0434\u043b\u044f \u043f\u0440\u043e\u0433\u043d\u043e\u0437\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u0438
 function.setmapbg=\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u043a\u0430\u0440\u0442\u0443-\u043f\u043e\u0434\u043b\u043e\u0436\u043a\u0443
 function.setpaths=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0443\u0442\u0438 \u043a \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430\u043c
 function.setmapbg=\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u043a\u0430\u0440\u0442\u0443-\u043f\u043e\u0434\u043b\u043e\u0436\u043a\u0443
 function.setpaths=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0443\u0442\u0438 \u043a \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430\u043c
+function.splitsegments=\u0420\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u044c \u0442\u0440\u0435\u043a \u043d\u0430 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u044b
+function.sewsegments=\u0421\u043a\u043b\u0435\u0438\u0442\u044c \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u044b \u0442\u0440\u0435\u043a\u0430 \u0432\u043e\u0435\u0434\u0438\u043d\u043e
 function.getgpsies=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0442\u0440\u0435\u043a\u0438
 function.uploadgpsies=\u0412\u044b\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0442\u0440\u0435\u043a \u043d\u0430 gpsies.com
 function.lookupsrtm=\u0412\u044b\u0441\u043e\u0442\u044b \u0432 SRTM
 function.getgpsies=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0442\u0440\u0435\u043a\u0438
 function.uploadgpsies=\u0412\u044b\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0442\u0440\u0435\u043a \u043d\u0430 gpsies.com
 function.lookupsrtm=\u0412\u044b\u0441\u043e\u0442\u044b \u0432 SRTM
+function.downloadsrtm=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c STRM 
 function.getwikipedia=\u0421\u0442\u0430\u0442\u044c\u044f \u043e \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432 \u0412\u0438\u043a\u0438
 function.searchwikipedianames=\u041f\u043e\u0438\u0441\u043a \u0441\u0442\u0430\u0442\u0435\u0439 \u0432 \u0412\u0438\u043a\u0438 \u043f\u043e \u0438\u043c\u0435\u043d\u0438
 function.downloadosm=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c OSM \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0430 \u0442\u0435\u0440\u0440\u0438\u0442\u043e\u0440\u0438\u044e
 function.getwikipedia=\u0421\u0442\u0430\u0442\u044c\u044f \u043e \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432 \u0412\u0438\u043a\u0438
 function.searchwikipedianames=\u041f\u043e\u0438\u0441\u043a \u0441\u0442\u0430\u0442\u0435\u0439 \u0432 \u0412\u0438\u043a\u0438 \u043f\u043e \u0438\u043c\u0435\u043d\u0438
 function.downloadosm=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c OSM \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0430 \u0442\u0435\u0440\u0440\u0438\u0442\u043e\u0440\u0438\u044e
@@ -133,6 +140,7 @@ function.checkversion=\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0
 function.saveconfig=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438
 function.diskcache=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043a\u0430\u0440\u0442\u044b \u043d\u0430 \u0434\u0438\u0441\u043a
 function.managetilecache=\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u0435\u0448\u0435\u043c
 function.saveconfig=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438
 function.diskcache=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043a\u0430\u0440\u0442\u044b \u043d\u0430 \u0434\u0438\u0441\u043a
 function.managetilecache=\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u0435\u0448\u0435\u043c
+function.getweatherforecast=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043f\u0440\u043e\u0433\u043d\u043e\u0437 \u043f\u043e\u0433\u043e\u0434\u044b
 
 # Dialogs
 dialog.exit.confirm.title=\u0412\u044b\u0445\u043e\u0434
 
 # Dialogs
 dialog.exit.confirm.title=\u0412\u044b\u0445\u043e\u0434
@@ -158,7 +166,9 @@ dialog.delimiter.other=\u0414\u0440\u0443\u0433\u043e\u0435
 dialog.openoptions.deliminfo.records=\u0437\u0430\u043f\u0438\u0441\u044c, \u0441
 dialog.openoptions.deliminfo.fields=\u043f\u043e\u043b\u0435
 dialog.openoptions.deliminfo.norecords=\u041d\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u0435\u0439
 dialog.openoptions.deliminfo.records=\u0437\u0430\u043f\u0438\u0441\u044c, \u0441
 dialog.openoptions.deliminfo.fields=\u043f\u043e\u043b\u0435
 dialog.openoptions.deliminfo.norecords=\u041d\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u0435\u0439
-dialog.openoptions.altitudeunits=\u0415\u0434\u0438\u043d\u0438\u0446\u044b \u0432\u044b\u0441\u043e\u0442
+dialog.openoptions.altitudeunits=\u0415\u0434\u0438\u043d\u0438\u0446\u044b \u0432\u044b\u0441\u043e\u0442\u044b
+dialog.openoptions.speedunits=\u0415\u0434\u0438\u043d\u0438\u0446\u044b \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438
+dialog.openoptions.vertspeedunits=\u0415\u0434\u0438\u043d\u0438\u0446\u044b
 dialog.open.contentsdoubled=\u042d\u0442\u043e\u0442 \u0444\u0430\u0439\u043b \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0434\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \u043a\u0430\u0436\u0434\u043e\u0439 \u0442\u043e\u0447\u043a\u0435,\n\u043e\u0434\u043d\u0430 \u043a\u0430\u043a \u043f\u0443\u0442\u0435\u0432\u0430\u044f \u0442\u043e\u0447\u043a\u0430 \u0438 \u043e\u0434\u043d\u0430 \u043a\u0430\u043a \u0442\u043e\u0447\u043a\u0430 \u0442\u0440\u0435\u043a\u0430
 dialog.selecttracks.intro=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0442\u0440\u0435\u043a(-\u0438) \u0434\u043b\u044f \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u044f
 dialog.selecttracks.noname=\u0411\u0435\u0437\u044b\u043c\u044f\u043d\u043d\u044b\u0439
 dialog.open.contentsdoubled=\u042d\u0442\u043e\u0442 \u0444\u0430\u0439\u043b \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0434\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \u043a\u0430\u0436\u0434\u043e\u0439 \u0442\u043e\u0447\u043a\u0435,\n\u043e\u0434\u043d\u0430 \u043a\u0430\u043a \u043f\u0443\u0442\u0435\u0432\u0430\u044f \u0442\u043e\u0447\u043a\u0430 \u0438 \u043e\u0434\u043d\u0430 \u043a\u0430\u043a \u0442\u043e\u0447\u043a\u0430 \u0442\u0440\u0435\u043a\u0430
 dialog.selecttracks.intro=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0442\u0440\u0435\u043a(-\u0438) \u0434\u043b\u044f \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u044f
 dialog.selecttracks.noname=\u0411\u0435\u0437\u044b\u043c\u044f\u043d\u043d\u044b\u0439
@@ -176,6 +186,11 @@ dialog.gpsload.save=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043
 dialog.gpssend.sendwaypoints=\u041f\u043e\u0441\u043b\u0430\u0442\u044c \u043f\u0443\u0442\u0435\u0432\u044b\u0435 \u0442\u043e\u0447\u043a\u0438
 dialog.gpssend.sendtracks=\u041f\u043e\u0441\u043b\u0430\u0442\u044c \u0442\u0440\u0435\u043a\u0438
 dialog.gpssend.trackname=\u0418\u043c\u044f \u0442\u0440\u0435\u043a\u0430
 dialog.gpssend.sendwaypoints=\u041f\u043e\u0441\u043b\u0430\u0442\u044c \u043f\u0443\u0442\u0435\u0432\u044b\u0435 \u0442\u043e\u0447\u043a\u0438
 dialog.gpssend.sendtracks=\u041f\u043e\u0441\u043b\u0430\u0442\u044c \u0442\u0440\u0435\u043a\u0438
 dialog.gpssend.trackname=\u0418\u043c\u044f \u0442\u0440\u0435\u043a\u0430
+dialog.gpsbabel.filters=\u0424\u0438\u043b\u044c\u0442\u0440\u044b
+dialog.addfilter.title=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0444\u0438\u043b\u044c\u0442\u0440
+dialog.gpsbabel.filter.distance=\u0420\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435
+dialog.gpsbabel.filter.interpolate=\u0418\u043d\u0442\u0435\u0440\u043f\u043e\u043b\u044f\u0446\u0438\u044f
+dialog.gpsbabel.filter.discard.numsats=\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043f\u0443\u0442\u043d\u0438\u043a\u043e\u0432 <
 dialog.saveoptions.title=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0444\u0430\u0439\u043b
 dialog.save.fieldstosave=\u041f\u043e\u043b\u044f \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435
 dialog.save.table.field=\u041f\u043e\u043b\u0435
 dialog.saveoptions.title=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0444\u0430\u0439\u043b
 dialog.save.fieldstosave=\u041f\u043e\u043b\u044f \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435
 dialog.save.table.field=\u041f\u043e\u043b\u0435
@@ -210,13 +225,25 @@ dialog.exportpov.modelstyle=\u0421\u0442\u0438\u043b\u044c \u043c\u043e\u0434\u0
 dialog.exportpov.ballsandsticks=\u041c\u044f\u0447\u0438 \u0438 \u043f\u0430\u043b\u043e\u0447\u043a\u0438
 dialog.exportpov.tubesandwalls=\u0422\u0440\u0443\u0431\u044b \u0438 \u0441\u0442\u0435\u043d\u044b
 dialog.3d.warningtracksize=\u0412\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0432 \u0442\u0440\u0435\u043a\u0435 \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0442\u043e\u0447\u0435\u043a - Java3D \u043c\u043e\u0436\u0435\u0442 \u0435\u0433\u043e \u043d\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c!\n\u0412\u044b \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c?
 dialog.exportpov.ballsandsticks=\u041c\u044f\u0447\u0438 \u0438 \u043f\u0430\u043b\u043e\u0447\u043a\u0438
 dialog.exportpov.tubesandwalls=\u0422\u0440\u0443\u0431\u044b \u0438 \u0441\u0442\u0435\u043d\u044b
 dialog.3d.warningtracksize=\u0412\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0432 \u0442\u0440\u0435\u043a\u0435 \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0442\u043e\u0447\u0435\u043a - Java3D \u043c\u043e\u0436\u0435\u0442 \u0435\u0433\u043e \u043d\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c!\n\u0412\u044b \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c?
-dialog.baseimage.mapsource=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430
-dialog.baseimage.zoom=\u041c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u0442
+dialog.3d.useterrain=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0440\u0435\u043b\u044c\u0435\u0444
+dialog.3d.terraingridsize=\u0420\u0430\u0437\u043c\u0435\u0440 \u0441\u0435\u0442\u043a\u0438
+dialog.exportpov.baseimage=\u041a\u0430\u0440\u0442\u0438\u043d\u043a\u0430 \u043e\u0441\u043d\u043e\u0432\u044b(\u043f\u043e\u0434\u043b\u043e\u0436\u043a\u0438)
+dialog.exportpov.cannotmakebaseimage=\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443 \u043e\u0441\u043d\u043e\u0432\u044b
+dialog.baseimage.title=\u0418\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043a\u0430\u0440\u0442\u044b
+dialog.baseimage.useimage=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435
+dialog.baseimage.mapsource=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a
+dialog.baseimage.zoom=\u041c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u0442\u044c
+dialog.baseimage.incomplete=\u041d\u0435 \u0432\u0441\u0435 \u0442\u0430\u0439\u043b\u044b \u0431\u044b\u043b\u0438 \u043d\u0430\u0439\u0434\u0435\u043d\u044b
+dialog.baseimage.tiles=\u0422\u0430\u0439\u043b\u044b
 dialog.baseimage.size=\u0420\u0430\u0437\u043c\u0435\u0440 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f
 dialog.exportsvg.text=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0434\u043b\u044f \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0430 SVG
 dialog.exportsvg.phi=\u0410\u0437\u0438\u043c\u0443\u0442 \u03d5
 dialog.exportsvg.theta=\u0423\u0433\u043e\u043b \u03b8
 dialog.exportsvg.gradients=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u0437\u0430\u0442\u0435\u043d\u0435\u043d\u0438\u044f
 dialog.baseimage.size=\u0420\u0430\u0437\u043c\u0435\u0440 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f
 dialog.exportsvg.text=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0434\u043b\u044f \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0430 SVG
 dialog.exportsvg.phi=\u0410\u0437\u0438\u043c\u0443\u0442 \u03d5
 dialog.exportsvg.theta=\u0423\u0433\u043e\u043b \u03b8
 dialog.exportsvg.gradients=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u0437\u0430\u0442\u0435\u043d\u0435\u043d\u0438\u044f
+dialog.exportimage.noimagepossible=\u041a\u0430\u0440\u0442\u0438\u043d\u043a\u0438 \u043a\u0430\u0440\u0442\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u044b \u043d\u0430 \u0434\u0438\u0441\u043a \u0434\u043b\u044f \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0430
+dialog.exportimage.drawtrack=\u0420\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u0442\u0440\u0435\u043a \u043d\u0430 \u043a\u0430\u0440\u0442\u0435
+dialog.exportimage.drawtrackpoints=\u041e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u0442\u043e\u0447\u043a\u0438 \u0442\u0440\u0435\u043a\u0430
+dialog.exportimage.textscalepercent=\u041c\u0430\u0441\u0448\u0442\u0430\u0431 \u0442\u0435\u043a\u0441\u0442\u0430 \u0432 %
 dialog.pointtype.desc=\u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0442\u0438\u043f\u044b \u0442\u043e\u0447\u0435\u043a:
 dialog.pointtype.track=\u0422\u043e\u0447\u043a\u0438 \u0442\u0440\u0435\u043a\u043e\u0432
 dialog.pointtype.waypoint=\u041f\u0443\u0442\u0435\u0432\u044b\u0435 \u0442\u043e\u0447\u043a\u0438
 dialog.pointtype.desc=\u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0442\u0438\u043f\u044b \u0442\u043e\u0447\u0435\u043a:
 dialog.pointtype.track=\u0422\u043e\u0447\u043a\u0438 \u0442\u0440\u0435\u043a\u043e\u0432
 dialog.pointtype.waypoint=\u041f\u0443\u0442\u0435\u0432\u044b\u0435 \u0442\u043e\u0447\u043a\u0438
@@ -236,7 +263,9 @@ dialog.undo.none.text=\u041d\u0435\u0442 \u0434\u0435\u0439\u0441\u0442\u0432\u0
 dialog.clearundo.title=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u0434\u043b\u044f \u043e\u0442\u043c\u0435\u043d\u044b
 dialog.clearundo.text=\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u0434\u043b\u044f \u043e\u0442\u043c\u0435\u043d\u044b?\n\u0421\u043f\u0438\u0441\u043e\u043a \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0447\u0438\u0449\u0435\u043d \u043d\u0430\u0432\u0441\u0435\u0433\u0434\u0430!
 dialog.pointedit.title=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u0447\u043a\u0443
 dialog.clearundo.title=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u0434\u043b\u044f \u043e\u0442\u043c\u0435\u043d\u044b
 dialog.clearundo.text=\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u0434\u043b\u044f \u043e\u0442\u043c\u0435\u043d\u044b?\n\u0421\u043f\u0438\u0441\u043e\u043a \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0447\u0438\u0449\u0435\u043d \u043d\u0430\u0432\u0441\u0435\u0433\u0434\u0430!
 dialog.pointedit.title=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u0447\u043a\u0443
+dialog.pointedit.intro=\u0412\u044b\u0431\u0438\u0440\u0430\u0439\u0442\u0435 \u043a\u0430\u0436\u0434\u043e\u0435 \u043f\u043e\u043b\u0435 \u0447\u0442\u043e\u0431\u044b \u0432\u0438\u0434\u0435\u0442\u044c \u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435
 dialog.pointedit.table.field=\u041f\u043e\u043b\u0435
 dialog.pointedit.table.field=\u041f\u043e\u043b\u0435
+dialog.pointedit.nofield=\u041f\u043e\u043b\u0435 \u043d\u0435 \u0432\u044b\u0431\u0440\u0430\u043d\u043e
 dialog.pointedit.table.value=\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435
 dialog.pointnameedit.name=\u0418\u043c\u044f \u043f\u0443\u0442\u0435\u0432\u043e\u0439 \u0442\u043e\u0447\u043a\u0438
 dialog.pointnameedit.uppercase=\u0412\u0435\u0440\u0445\u043d\u0438\u0439 \u0440\u0435\u0433\u0438\u0441\u0442\u0440
 dialog.pointedit.table.value=\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435
 dialog.pointnameedit.name=\u0418\u043c\u044f \u043f\u0443\u0442\u0435\u0432\u043e\u0439 \u0442\u043e\u0447\u043a\u0438
 dialog.pointnameedit.uppercase=\u0412\u0435\u0440\u0445\u043d\u0438\u0439 \u0440\u0435\u0433\u0438\u0441\u0442\u0440
@@ -280,16 +309,27 @@ dialog.fullrangedetails.intro=\u0414\u0435\u0442\u0430\u043b\u0438\u0437\u0430\u
 dialog.fullrangedetails.coltotal=\u0412\u043a\u043b\u044e\u0447\u0430\u044f \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u0438
 dialog.fullrangedetails.colsegments=\u0411\u0435\u0437 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u043e\u0432
 dialog.estimatetime.details=\u0414\u0435\u0442\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f
 dialog.fullrangedetails.coltotal=\u0412\u043a\u043b\u044e\u0447\u0430\u044f \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u0438
 dialog.fullrangedetails.colsegments=\u0411\u0435\u0437 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u043e\u0432
 dialog.estimatetime.details=\u0414\u0435\u0442\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f
+dialog.estimatetime.gentle=\u041f\u043b\u0430\u0432\u043d\u043e
+dialog.estimatetime.steep=\u0420\u0435\u0437\u043a\u043e
 dialog.estimatetime.climb=\u041f\u043e\u0434\u044a\u0435\u043c
 dialog.estimatetime.descent=\u0421\u043f\u0443\u0441\u043a
 dialog.estimatetime.parameters=\u041f\u0430\u0440\u0430\u0301\u043c\u0435\u0442\u0440\u044b
 dialog.estimatetime.climb=\u041f\u043e\u0434\u044a\u0435\u043c
 dialog.estimatetime.descent=\u0421\u043f\u0443\u0441\u043a
 dialog.estimatetime.parameters=\u041f\u0430\u0440\u0430\u0301\u043c\u0435\u0442\u0440\u044b
+dialog.estimatetime.parameters.timefor=\u0412\u0440\u0435\u043c\u044f \u0434\u043b\u044f
+dialog.estimatetime.results=\u0412\u043e\u0442:
+dialog.estimatetime.results.estimatedtime=\u041f\u0440\u043e\u0433\u043d\u043e\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f
+dialog.estimatetime.results.actualtime=\u0420\u0435\u0430\u043b\u044c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f
+dialog.estimatetime.error.noaltitudes=\u0412\u044b\u0431\u043e\u0440\u043a\u0430 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e \u0432\u044b\u0441\u043e\u0442\u0435
+dialog.learnestimationparams.averageerror=\u0421\u0440\u0435\u0434\u043d\u044f\u044f \u043e\u0448\u0438\u0431\u043a\u0430 (%)
+dialog.learnestimationparams.weight.current=\u0442\u0435\u043a\u0443\u0449\u0435\u0435
+dialog.learnestimationparams.weight.calculated=\u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043d\u043d\u043e\u0435
+dialog.learnestimationparams.weight.50pc=\u0421\u0440\u0435\u0434\u043d\u0435\u0435 \u043e\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0438 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043d\u043d\u043e\u0433\u043e
+dialog.learnestimationparams.weight.100pccalculated=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435
 dialog.setmapbg.intro=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0432 \u0441\u043f\u0438\u0441\u043a\u0435 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0444\u043e\u043d\u0430 \u0438\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u043d\u043e\u0432\u044b\u0439
 dialog.addmapsource.title=\u0414\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u043d\u043e\u0432\u044b\u0439 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0444\u043e\u043d\u0430
 dialog.addmapsource.sourcename=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430
 dialog.addmapsource.layer1url=URL \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0441\u043b\u043e\u044f
 dialog.addmapsource.layer2url=\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0439 URL \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u043b\u043e\u044f
 dialog.addmapsource.maxzoom=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f
 dialog.setmapbg.intro=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0432 \u0441\u043f\u0438\u0441\u043a\u0435 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0444\u043e\u043d\u0430 \u0438\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u043d\u043e\u0432\u044b\u0439
 dialog.addmapsource.title=\u0414\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u043d\u043e\u0432\u044b\u0439 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0444\u043e\u043d\u0430
 dialog.addmapsource.sourcename=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430
 dialog.addmapsource.layer1url=URL \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0441\u043b\u043e\u044f
 dialog.addmapsource.layer2url=\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0439 URL \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u043b\u043e\u044f
 dialog.addmapsource.maxzoom=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f
-dialog.addmapsource.cloudstyle=\u041d\u043e\u043c\u0435\u0440 \u0441\u0442\u0438\u043b\u044f
 dialog.addmapsource.noname=\u0411\u0435\u0437\u044b\u043c\u044f\u043d\u043d\u044b\u0439
 dialog.gpsies.column.name=\u0418\u043c\u044f \u0442\u0440\u0435\u043a\u0430
 dialog.gpsies.column.length=\u0414\u043b\u0438\u043d\u0430
 dialog.addmapsource.noname=\u0411\u0435\u0437\u044b\u043c\u044f\u043d\u043d\u044b\u0439
 dialog.gpsies.column.name=\u0418\u043c\u044f \u0442\u0440\u0435\u043a\u0430
 dialog.gpsies.column.length=\u0414\u043b\u0438\u043d\u0430
@@ -474,6 +514,28 @@ dialog.deletefieldvalues.nofields=\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u0
 dialog.setlinewidth.text=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0442\u043e\u043b\u0449\u0438\u043d\u0443 \u043b\u0438\u043d\u0438\u0439 \u0434\u043b\u044f \u0442\u0440\u0435\u043a\u043e\u0432 (1-4)
 dialog.downloadosm.desc=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 OSM \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438:
 dialog.searchwikipedianames.search=\u041f\u043e\u0438\u0441\u043a \u0434\u043b\u044f:
 dialog.setlinewidth.text=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0442\u043e\u043b\u0449\u0438\u043d\u0443 \u043b\u0438\u043d\u0438\u0439 \u0434\u043b\u044f \u0442\u0440\u0435\u043a\u043e\u0432 (1-4)
 dialog.downloadosm.desc=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 OSM \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438:
 dialog.searchwikipedianames.search=\u041f\u043e\u0438\u0441\u043a \u0434\u043b\u044f:
+dialog.weather.location=\u041c\u0435\u0441\u0442\u043e
+dialog.weather.update=\u041f\u0440\u043e\u0433\u043d\u043e\u0437 \u043e\u0431\u043d\u043e\u0432\u043b\u0451\u043d
+dialog.weather.sunrise=\u0412\u043e\u0441\u0445\u043e\u0434
+dialog.weather.sunset=\u0417\u0430\u043a\u0430\u0442
+dialog.weather.temperatureunits=\u0422\u0435\u043c\u043f\u0435\u0440\u0430\u0442\u0443\u0440\u044b
+dialog.weather.currentforecast=\u041f\u043e\u0433\u043e\u0434\u0430 \u0441\u0435\u0439\u0447\u0430\u0441
+dialog.weather.dailyforecast=\u041f\u0440\u043e\u0433\u043d\u043e\u0437 \u043d\u0430 \u0434\u0435\u043d\u044c
+dialog.weather.3hourlyforecast=\u041f\u0440\u043e\u0433\u043d\u043e\u0437 \u043d\u0430 3 \u0447\u0430\u0441\u0430
+dialog.weather.day.now=\u0422\u0435\u043a\u0443\u0449\u0430\u044f \u043f\u043e\u0433\u043e\u0434\u0430
+dialog.weather.day.today=\u0421\u0435\u0433\u043e\u0434\u043d\u044f
+dialog.weather.day.tomorrow=\u0417\u0430\u0432\u0442\u0440\u0430
+dialog.weather.day.monday=\u041f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a
+dialog.weather.day.tuesday=\u0412\u0442\u043e\u0440\u043d\u0438\u043a
+dialog.weather.day.wednesday=\u0421\u0440\u0435\u0434\u0430
+dialog.weather.day.thursday=\u0427\u0435\u0442\u0432\u0435\u0440\u0433
+dialog.weather.day.friday=\u041f\u044f\u0442\u043d\u0438\u0446\u0430
+dialog.weather.day.saturday=\u0421\u0443\u0431\u0431\u043e\u0442\u0430
+dialog.weather.day.sunday=\u0412\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d\u044c\u0435
+dialog.weather.wind=\u0412\u0435\u0442\u0435\u0440
+dialog.weather.temp=\u0422\u00b0
+dialog.weather.humidity=\u0412\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u044c
+dialog.weather.creditnotice=\u0414\u043B\u044F \u043F\u043E\u043B\u0443\u0447\u0435\u043D\u0438\u044F \u0434\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u043E\u0439 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u0438 \u043E\u0431\u0440\u0430\u0442\u0438\u0442\u0435\u0441\u044C \u043F\u043E openweathermap.org.
 
 # 3d window
 dialog.3d.title=GpsPrune 3D-\u0432\u0438\u0434
 
 # 3d window
 dialog.3d.title=GpsPrune 3D-\u0432\u0438\u0434
@@ -492,6 +554,8 @@ confirm.addtimeoffset=\u041e\u0442\u043c\u0435\u0442\u043a\u0430 \u0432\u0440\u0
 confirm.addaltitudeoffset=\u041e\u0442\u043c\u0435\u0442\u043a\u0430 \u0432\u044b\u0441\u043e\u0442\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430
 confirm.rearrangewaypoints=\u041f\u0443\u0442\u0435\u0432\u0430\u044f \u0442\u043e\u0447\u043a\u0430 \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u0430\u043d\u0430
 confirm.rearrangephotos=\u0424\u043e\u0442\u043e \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u0430\u043d\u043e
 confirm.addaltitudeoffset=\u041e\u0442\u043c\u0435\u0442\u043a\u0430 \u0432\u044b\u0441\u043e\u0442\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430
 confirm.rearrangewaypoints=\u041f\u0443\u0442\u0435\u0432\u0430\u044f \u0442\u043e\u0447\u043a\u0430 \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u0430\u043d\u0430
 confirm.rearrangephotos=\u0424\u043e\u0442\u043e \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u0430\u043d\u043e
+confirm.splitsegments=\u0421\u0434\u0435\u043b\u0430\u043d\u043e %d \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0439 \u043d\u0430 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u044b
+confirm.sewsegments=\u0421\u0434\u0435\u043b\u0430\u043d\u043e %d \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u043e\u0432
 confirm.cutandmove=\u041e\u0442\u043e\u0431\u0440\u0430\u043d\u043d\u043e\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u043e
 confirm.interpolate=\u0422\u043e\u0447\u043a\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b
 confirm.convertnamestotimes=\u0418\u043c\u044f \u043f\u0443\u0442\u0435\u0432\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u043f\u0435\u0440\u0435\u0432\u0435\u0434\u0435\u043d\u043e
 confirm.cutandmove=\u041e\u0442\u043e\u0431\u0440\u0430\u043d\u043d\u043e\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u043e
 confirm.interpolate=\u0422\u043e\u0447\u043a\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b
 confirm.convertnamestotimes=\u0418\u043c\u044f \u043f\u0443\u0442\u0435\u0432\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u043f\u0435\u0440\u0435\u0432\u0435\u0434\u0435\u043d\u043e
@@ -510,12 +574,15 @@ confirm.createpoint=\u0442\u043e\u0447\u043a\u0430 \u0441\u043e\u0437\u0434\u043
 confirm.rotatephoto=\u0444\u043e\u0442\u043e \u043f\u043e\u0432\u0435\u0440\u043d\u0443\u0442\u043e
 confirm.running=\u0420\u0430\u0431\u043e\u0442\u0430\u044e...
 confirm.lookupsrtm=\u041d\u0430\u0439\u0434\u0435\u043d\u043e %d \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432\u044b\u0441\u043e\u0442\u044b
 confirm.rotatephoto=\u0444\u043e\u0442\u043e \u043f\u043e\u0432\u0435\u0440\u043d\u0443\u0442\u043e
 confirm.running=\u0420\u0430\u0431\u043e\u0442\u0430\u044e...
 confirm.lookupsrtm=\u041d\u0430\u0439\u0434\u0435\u043d\u043e %d \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432\u044b\u0441\u043e\u0442\u044b
+confirm.downloadsrtm=\u0417\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e %d \u0444\u0430\u0439\u043b\u043e\u0432 \u0432 \u043a\u044d\u0448
+confirm.downloadsrtm.1=\u0417\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e %d \u0444\u0430\u0439\u043b\u043e\u0432 \u0432 \u043a\u044d\u0448
+confirm.downloadsrtm.none=\u0412\u0441\u0435 \u0444\u0430\u0439\u043b\u044b \u0443\u0436\u0435 \u0432 \u043a\u044d\u0448\u0435
 confirm.deletefieldvalues=\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u044b
 confirm.audioload=\u0424\u0430\u0439\u043b\u044b \u0437\u0432\u0443\u043a\u043e\u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b
 confirm.correlateaudios.single=\u0417\u0432\u0443\u043a\u043e\u0437\u0430\u043f\u0438\u0441\u044c \u0431\u044b\u043b\u0438 \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430
 confirm.correlateaudios.multi=\u0417\u0432\u0443\u043a\u043e\u0437\u0430\u043f\u0438\u0441\u0438 \u0431\u044b\u043b\u0438 \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b
 
 confirm.deletefieldvalues=\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u044b
 confirm.audioload=\u0424\u0430\u0439\u043b\u044b \u0437\u0432\u0443\u043a\u043e\u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b
 confirm.correlateaudios.single=\u0417\u0432\u0443\u043a\u043e\u0437\u0430\u043f\u0438\u0441\u044c \u0431\u044b\u043b\u0438 \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430
 confirm.correlateaudios.multi=\u0417\u0432\u0443\u043a\u043e\u0437\u0430\u043f\u0438\u0441\u0438 \u0431\u044b\u043b\u0438 \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b
 
-# Tips
+# Tips, shown just once when appropriate
 tip.title=\u0421\u043e\u0432\u0435\u0442
 tip.manuallycorrelateone=\u041f\u0440\u0438 \u0440\u0443\u0447\u043d\u043e\u043c \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u043a\u0440\u0430\u0439\u043d\u0438\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u043c\u0435\u0442\u043a\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043d\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438.
 
 tip.title=\u0421\u043e\u0432\u0435\u0442
 tip.manuallycorrelateone=\u041f\u0440\u0438 \u0440\u0443\u0447\u043d\u043e\u043c \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u043a\u0440\u0430\u0439\u043d\u0438\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u043c\u0435\u0442\u043a\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043d\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438.
 
@@ -536,6 +603,7 @@ button.yes=\u0414\u0430
 button.no=\u041d\u0435\u0442
 button.yestoall=\u0414\u0430 \u0434\u043b\u044f \u0432\u0441\u0435\u0445
 button.notoall=\u041d\u0435\u0442 \u0434\u043b\u044f \u0432\u0441\u0435\u0445
 button.no=\u041d\u0435\u0442
 button.yestoall=\u0414\u0430 \u0434\u043b\u044f \u0432\u0441\u0435\u0445
 button.notoall=\u041d\u0435\u0442 \u0434\u043b\u044f \u0432\u0441\u0435\u0445
+button.always=\u0412\u0441\u0435\u0433\u0434\u0430
 button.select=\u0412\u044b\u0431\u0440\u0430\u0442\u044c
 button.selectall=\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u0432\u0441\u0435
 button.selectnone=\u041e\u0442\u043c\u0435\u043d\u0442\u0438\u0442\u044c \u0432\u044b\u0431\u043e\u0440\u043a\u0443
 button.select=\u0412\u044b\u0431\u0440\u0430\u0442\u044c
 button.selectall=\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u0432\u0441\u0435
 button.selectnone=\u041e\u0442\u043c\u0435\u043d\u0442\u0438\u0442\u044c \u0432\u044b\u0431\u043e\u0440\u043a\u0443
@@ -550,6 +618,7 @@ button.browse=\u041e\u0431\u0437\u043e\u0440...
 button.addnew=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u043e\u0435
 button.delete=\u0423\u0434\u0430\u043b\u0438\u0442\u044c
 button.manage=\u0423\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c
 button.addnew=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u043e\u0435
 button.delete=\u0423\u0434\u0430\u043b\u0438\u0442\u044c
 button.manage=\u0423\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c
+button.combine=\u0421\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u0442\u044c
 
 # File types
 filetype.txt=TXT \u0444\u0430\u0439\u043b\u044b
 
 # File types
 filetype.txt=TXT \u0444\u0430\u0439\u043b\u044b
@@ -567,6 +636,7 @@ filetype.audio=MP3, OGG, WAV \u0444\u0430\u0439\u043b\u044b
 display.nodata=\u0414\u0430\u043d\u043d\u044b\u0435 \u043d\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u044b
 display.noaltitudes=\u0414\u0430\u043d\u043d\u044b\u0435 \u0432 \u0442\u0440\u0435\u043a\u0435 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u0432\u044b\u0441\u043e\u0442\u043d\u044b\u0445 \u043e\u0442\u043c\u0435\u0442\u043e\u043a
 display.notimestamps=\u0414\u0430\u043d\u043d\u044b\u0435 \u0432 \u0442\u0440\u0435\u043a\u0435 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u043e\u0442\u043c\u0435\u0442\u043e\u043a \u0432\u0440\u0435\u043c\u0435\u043d\u0438
 display.nodata=\u0414\u0430\u043d\u043d\u044b\u0435 \u043d\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u044b
 display.noaltitudes=\u0414\u0430\u043d\u043d\u044b\u0435 \u0432 \u0442\u0440\u0435\u043a\u0435 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u0432\u044b\u0441\u043e\u0442\u043d\u044b\u0445 \u043e\u0442\u043c\u0435\u0442\u043e\u043a
 display.notimestamps=\u0414\u0430\u043d\u043d\u044b\u0435 \u0432 \u0442\u0440\u0435\u043a\u0435 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u043e\u0442\u043c\u0435\u0442\u043e\u043a \u0432\u0440\u0435\u043c\u0435\u043d\u0438
+display.novalues=\u0412 \u0442\u0440\u0435\u043a\u0435 \u043d\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u043b\u044f
 details.trackdetails=\u0414\u0435\u0442\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0442\u0440\u0435\u043a\u0430
 details.notrack=\u0422\u0440\u0435\u043a \u043d\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d
 details.track.points=\u0422\u043e\u0447\u043a\u0438(-\u0435\u043a)
 details.trackdetails=\u0414\u0435\u0442\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0442\u0440\u0435\u043a\u0430
 details.notrack=\u0422\u0440\u0435\u043a \u043d\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d
 details.track.points=\u0422\u043e\u0447\u043a\u0438(-\u0435\u043a)
@@ -656,6 +726,10 @@ units.degminsec=\u0413\u0440\u0430\u0434-\u043c\u0438\u043d-\u0441\u0435\u043a
 units.degmin=\u0413\u0440\u0430\u0434-\u043c\u0438\u043d
 units.deg=\u0413\u0440\u0430\u0434\u0443\u0441\u044b
 units.iso8601=ISO 8601
 units.degmin=\u0413\u0440\u0430\u0434-\u043c\u0438\u043d
 units.deg=\u0413\u0440\u0430\u0434\u0443\u0441\u044b
 units.iso8601=ISO 8601
+units.degreescelsius=\u0426\u0435\u043b\u044c\u0441\u0438\u0439
+units.degreescelsius.short=\u00b0C
+units.degreesfahrenheit=\u0424\u0430\u0440\u0435\u043d\u0433\u0435\u0439\u0442
+units.degreesfahrenheit.short=\u00b0F
 
 # How to combine conditions, such as filters
 logic.and=\u0438
 
 # How to combine conditions, such as filters
 logic.and=\u0438
@@ -686,6 +760,8 @@ undo.deletemarked=\u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0442\u043e\u0447\
 undo.insert=\u0432\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0442\u043e\u0447\u043a\u0438
 undo.reverse=\u043f\u0435\u0440\u0435\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b
 undo.mergetracksegments=\u0441\u043b\u0438\u044f\u043d\u0438\u0435 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u043e\u0432 \u0442\u0440\u0435\u043a\u0430
 undo.insert=\u0432\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0442\u043e\u0447\u043a\u0438
 undo.reverse=\u043f\u0435\u0440\u0435\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b
 undo.mergetracksegments=\u0441\u043b\u0438\u044f\u043d\u0438\u0435 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u043e\u0432 \u0442\u0440\u0435\u043a\u0430
+undo.splitsegments=\u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u044c \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u044b \u0442\u0440\u0435\u043a\u0430
+undo.sewsegments=\u0441\u043a\u043b\u0435\u0438\u0442\u044c \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u044b \u0442\u0440\u0435\u043a\u0430
 undo.addtimeoffset=\u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u0442\u043c\u0435\u0442\u043a\u0443 \u0432\u0440\u0435\u043c\u0435\u043d\u0438
 undo.addaltitudeoffset=\u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u0442\u043c\u0435\u0442\u043a\u0443 \u0432\u044b\u0441\u043e\u0442\u044b
 undo.rearrangewaypoints=\u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043f\u0443\u0442\u0435\u0432\u044b\u0435 \u0442\u043e\u0447\u043a\u0438
 undo.addtimeoffset=\u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u0442\u043c\u0435\u0442\u043a\u0443 \u0432\u0440\u0435\u043c\u0435\u043d\u0438
 undo.addaltitudeoffset=\u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u0442\u043c\u0435\u0442\u043a\u0443 \u0432\u044b\u0441\u043e\u0442\u044b
 undo.rearrangewaypoints=\u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043f\u0443\u0442\u0435\u0432\u044b\u0435 \u0442\u043e\u0447\u043a\u0438
@@ -745,3 +821,4 @@ error.cache.notthere=\u041f\u0430\u043f\u043a\u0430 \u043a\u044d\u0448\u0430 \u0
 error.cache.empty=\u041f\u0430\u043f\u043a\u0430 \u043a\u044d\u0448\u0430 \u0441 \u0442\u0430\u0439\u043b\u0430\u043c\u0438 \u043f\u0443\u0441\u0442\u0430
 error.cache.cannotdelete=\u041d\u0435\u0442 \u0442\u0430\u0439\u043b\u043e\u0432, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0434\u043b\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f
 error.interpolate.invalidparameter=\u041d\u043e\u043c\u0435\u0440 \u0442\u043e\u0447\u043a\u0438 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043e\u0442 1 \u0434\u043e 1000
 error.cache.empty=\u041f\u0430\u043f\u043a\u0430 \u043a\u044d\u0448\u0430 \u0441 \u0442\u0430\u0439\u043b\u0430\u043c\u0438 \u043f\u0443\u0441\u0442\u0430
 error.cache.cannotdelete=\u041d\u0435\u0442 \u0442\u0430\u0439\u043b\u043e\u0432, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0434\u043b\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f
 error.interpolate.invalidparameter=\u041d\u043e\u043c\u0435\u0440 \u0442\u043e\u0447\u043a\u0438 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043e\u0442 1 \u0434\u043e 1000
+error.tracksplit.nosplit=\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u044c \u0442\u0440\u0435\u043a
index eeffcd930a60f77c5938c68333e0ec67fd25dd04..7f421c8d4070689bf0f93de6eebd01dcd1e751e3 100644 (file)
 # Swedish entries
 
 # Menu entries
 # Swedish entries
 
 # Menu entries
-menu.file=Fil
+menu.file=Arkiv
 menu.file.addphotos=L\u00e4gg till foto
 menu.file.recentfiles=Senaste filer
 menu.file.save=Spara som text
 menu.file.exit=Avsluta
 menu.track=Sp\u00e5r
 menu.track.undo=\u00c5ngra
 menu.file.addphotos=L\u00e4gg till foto
 menu.file.recentfiles=Senaste filer
 menu.file.save=Spara som text
 menu.file.exit=Avsluta
 menu.track=Sp\u00e5r
 menu.track.undo=\u00c5ngra
-menu.track.clearundo=Rensa \u00e5ngra
+menu.track.clearundo=Rensa \u00e5ngra-historik
 menu.track.markrectangle=Markera punkter i rektangel
 menu.track.deletemarked=Radera markerade punkter
 menu.track.markrectangle=Markera punkter i rektangel
 menu.track.deletemarked=Radera markerade punkter
-menu.track.rearrange=Arrangera om ruttpunkter
+menu.track.rearrange=Ordna waypoints
 menu.track.rearrange.start=Alla till b\u00f6rjan av fil
 menu.track.rearrange.end=Alla till slut av fil
 menu.track.rearrange.nearest=Varje till n\u00e4rmaste sp\u00e5rpunkt
 menu.track.rearrange.start=Alla till b\u00f6rjan av fil
 menu.track.rearrange.end=Alla till slut av fil
 menu.track.rearrange.nearest=Varje till n\u00e4rmaste sp\u00e5rpunkt
-menu.range=Omr\u00e5de
+menu.range=Intervall
 menu.range.all=V\u00e4lj alla
 menu.range.none=V\u00e4lj ingen
 menu.range.all=V\u00e4lj alla
 menu.range.none=V\u00e4lj ingen
-menu.range.start=St\u00e4ll in b\u00f6rjan p\u00e5 omr\u00e5de
-menu.range.end=St\u00e4ll in slut p\u00e5 omr\u00e5de
+menu.range.start=S\u00e4tt till b\u00f6rjan av intervall
+menu.range.end=S\u00e4tt till slutet av intervall
 menu.range.average=Medelv\u00e4rdesval
 menu.range.average=Medelv\u00e4rdesval
-menu.range.reverse=Backa omr\u00e5de
+menu.range.reverse=V\u00e4nd intervall
 menu.range.mergetracksegments=Sl\u00e5 ihop sp\u00e5rsegment
 menu.range.cutandmove=Klipp och flytta urval
 menu.point=Punkt
 menu.point.editpoint=Redigera punkt
 menu.point.deletepoint=Radera punkt
 menu.photo=Foto
 menu.range.mergetracksegments=Sl\u00e5 ihop sp\u00e5rsegment
 menu.range.cutandmove=Klipp och flytta urval
 menu.point=Punkt
 menu.point.editpoint=Redigera punkt
 menu.point.deletepoint=Radera punkt
 menu.photo=Foto
-menu.photo.saveexif=Spara och avsluta
+menu.photo.saveexif=Spara till Exif
 menu.audio=Ljud
 menu.audio=Ljud
-menu.view=Vy
-menu.view.showsidebars=Visa sidolister
-menu.view.browser=Karta i ett l\u00e4sarf\u00f6nster
+menu.view=Visa
+menu.view.showsidebars=Visa sidopaneler
+menu.view.browser=Karta i webbl\u00e4sare
 menu.view.browser.google=Google Maps
 menu.view.browser.openstreetmap=Openstreetmap
 menu.view.browser.mapquest=Mapquest
 menu.view.browser.yahoo=Yahoo maps
 menu.view.browser.bing=Bing maps
 menu.settings=Inst\u00e4llningar
 menu.view.browser.google=Google Maps
 menu.view.browser.openstreetmap=Openstreetmap
 menu.view.browser.mapquest=Mapquest
 menu.view.browser.yahoo=Yahoo maps
 menu.view.browser.bing=Bing maps
 menu.settings=Inst\u00e4llningar
-menu.settings.onlinemode=Ladda karta fr\u00e5n Internet
+menu.settings.onlinemode=H\u00e4mta kartor fr\u00e5n Internet
 menu.settings.autosave=Autospara inst\u00e4llningar vid avslut
 menu.help=Hj\u00e4lp
 menu.settings.autosave=Autospara inst\u00e4llningar vid avslut
 menu.help=Hj\u00e4lp
+# Popup menu for map
+menu.map.zoomin=Zooma ut
+menu.map.zoomout=Zooma in
+menu.map.zoomfull=Zooma till passning
+menu.map.newpoint=Skapa ny punkt
+menu.map.drawpoints=Skapa en serie punkter
+menu.map.connect=F\u00f6rbind sp\u00e5rpunkter
+menu.map.autopan=Panorera automatiskt
+menu.map.showmap=Visa karta
+menu.map.showscalebar=Visa skala
+menu.map.editmode=Redigeringsl\u00e4ge
 
 # Alt keys for menus
 
 # Alt keys for menus
-altkey.menu.file=F
+altkey.menu.file=A
 altkey.menu.track=S
 altkey.menu.track=S
-altkey.menu.range=O
+altkey.menu.range=I
 altkey.menu.point=P
 altkey.menu.view=V
 altkey.menu.point=P
 altkey.menu.view=V
-altkey.menu.photo=T
+altkey.menu.photo=F
 altkey.menu.audio=L
 altkey.menu.settings=I
 altkey.menu.help=H
 
 altkey.menu.audio=L
 altkey.menu.settings=I
 altkey.menu.help=H
 
+# Ctrl shortcuts for menu items
+shortcut.menu.file.open=O
+shortcut.menu.file.load=L
+shortcut.menu.file.save=S
+shortcut.menu.track.undo=Z
+shortcut.menu.range.all=A
+shortcut.menu.help.help=H
+
+# Functions
+function.open=\u00d6ppna fil
+function.importwithgpsbabel=Importera fil med GPSBabel
+function.loadfromgps=Ladda fr\u00e5n GPS
+function.sendtogps=Skicka till GPS
+function.exportkml=Exportera KML
+function.exportgpx=Exportera GPX
+function.exportpov=Exportera POV
+function.exportsvg=Exportera SVG
+function.exportimage=Exportera bildfil
+function.editwaypointname=Redigera namn p\u00e5 waypoint
+function.compress=Komprimera sp\u00e5r
+function.deleterange=Radera intervall
+function.croptrack=Besk\u00e4r sp\u00e5r till intervall
+function.interpolate=Interpolera punkter
+function.addtimeoffset=Infoga tidsoffset
+function.addaltitudeoffset=Infoga h\u00f6jdoffset
+function.convertnamestotimes=Omvandla waypointnamn till tidpunkter
+function.findwaypoint=S\u00f6k waypoint
+function.pastecoordinates=Infoga koordinater
+function.charts=Diagram
+function.show3d=3D-vy
+function.distances=Avst\u00e5nd
+function.estimatetime=Uppskatta tid
+
 openweathermap.lang=se
 openweathermap.lang=se
index e509978ee6a2cf3ddb10c338f178b19c1a6ad479..4baf0dec79adc56ea46040281094a9422585f01a 100644 (file)
@@ -269,7 +269,6 @@ dialog.saveconfig.prune.exiftoolpath=exiftool'un yeriyolu
 dialog.saveconfig.prune.mapserverindex=Harita sunucunun index
 dialog.saveconfig.prune.mapserverurl=Harita sunucunun adresi
 dialog.saveconfig.prune.kmzimagewidth=KMZ resim geni\u015fli\u011fi
 dialog.saveconfig.prune.mapserverindex=Harita sunucunun index
 dialog.saveconfig.prune.mapserverurl=Harita sunucunun adresi
 dialog.saveconfig.prune.kmzimagewidth=KMZ resim geni\u015fli\u011fi
-dialog.saveconfig.prune.kmzimageheight=KMZ resim y\u00fcksekli\u011fi
 dialog.setpaths.intro=\u0130ste\u011fe ba\u011fl\u0131 a\u015fa\u011f\u0131daki uygulamalar\u0131n veriyolu kaydedebilirsin:
 dialog.addaltitude.noaltitudes=Se\u00e7ili s\u0131rada y\u00fckseklik bilgisi bulunmad\u0131
 dialog.addaltitude.desc=Eklenecek y\u00fckseklik ofseti
 dialog.setpaths.intro=\u0130ste\u011fe ba\u011fl\u0131 a\u015fa\u011f\u0131daki uygulamalar\u0131n veriyolu kaydedebilirsin:
 dialog.addaltitude.noaltitudes=Se\u00e7ili s\u0131rada y\u00fckseklik bilgisi bulunmad\u0131
 dialog.addaltitude.desc=Eklenecek y\u00fckseklik ofseti
index d0225139fddbec476e7b110ddd2f0d1f91f6bc66..1fcca74ebd5a4ff88cb9c1871227b712846a3907 100644 (file)
@@ -358,7 +358,6 @@ dialog.addmapsource.sourcename=\u5730\u56fe\u6765\u6e90\u540d\u79f0
 dialog.addmapsource.layer1url=\u7b2c\u4e00\u5c42URL
 dialog.addmapsource.layer2url=\u53ef\u9009\u7b2c\u4e8c\u5c42URL
 dialog.addmapsource.maxzoom=\u6700\u5927\u7f29\u653e\u7ea7\u6570
 dialog.addmapsource.layer1url=\u7b2c\u4e00\u5c42URL
 dialog.addmapsource.layer2url=\u53ef\u9009\u7b2c\u4e8c\u5c42URL
 dialog.addmapsource.maxzoom=\u6700\u5927\u7f29\u653e\u7ea7\u6570
-dialog.addmapsource.cloudstyle=\u6837\u5f0f\u53f7
 dialog.addmapsource.noname=\u672a\u547d\u540d
 dialog.gpsies.column.name=\u8f68\u8ff9\u540d\u79f0
 dialog.gpsies.column.length=\u957f\u5ea6
 dialog.addmapsource.noname=\u672a\u547d\u540d
 dialog.gpsies.column.name=\u8f68\u8ff9\u540d\u79f0
 dialog.gpsies.column.length=\u957f\u5ea6
@@ -601,6 +600,7 @@ confirm.rotatephoto=\u7167\u7247\u5df2\u65cb\u8f6c
 confirm.running=\u8bf7\u7a0d\u7b49...
 confirm.lookupsrtm=\u627e\u5230 %d \u9ad8\u5ea6\u503c
 confirm.downloadsrtm=\u4e0b\u8f7d %d \u9ad8\u5ea6\u6587\u4ef6\u5230\u7f13\u5b58\u4e2d
 confirm.running=\u8bf7\u7a0d\u7b49...
 confirm.lookupsrtm=\u627e\u5230 %d \u9ad8\u5ea6\u503c
 confirm.downloadsrtm=\u4e0b\u8f7d %d \u9ad8\u5ea6\u6587\u4ef6\u5230\u7f13\u5b58\u4e2d
+confirm.downloadsrtm.1=\u4e0b\u8f7d %d \u9ad8\u5ea6\u6587\u4ef6\u5230\u7f13\u5b58\u4e2d
 confirm.downloadsrtm.none=\u65e0\u9700\u4e0b\u8f7d\uff0c\u6587\u4ef6\u5df2\u5b58\u50a8\u5728\u7f13\u5b58\u4e2d
 confirm.deletefieldvalues=\u533a\u57df\u6570\u636e\u5df2\u5220\u9664
 confirm.audioload=\u5df2\u6dfb\u52a0\u58f0\u97f3\u6587\u4ef6
 confirm.downloadsrtm.none=\u65e0\u9700\u4e0b\u8f7d\uff0c\u6587\u4ef6\u5df2\u5b58\u50a8\u5728\u7f13\u5b58\u4e2d
 confirm.deletefieldvalues=\u533a\u57df\u6570\u636e\u5df2\u5220\u9664
 confirm.audioload=\u5df2\u6dfb\u52a0\u58f0\u97f3\u6587\u4ef6
index 16030ca64cbb03223c4abd0ca32c89f0c4c8a0db..39359c1726f82167bc0ae848f66b8754ead6c0f4 100644 (file)
@@ -26,8 +26,10 @@ public abstract class BabelFileFormats
                {
                        final String[] suffixes = getColumn(2);
                        for (int i=0; i<suffixes.length; i++)
                {
                        final String[] suffixes = getColumn(2);
                        for (int i=0; i<suffixes.length; i++)
+                       {
                                if (suffixes[i] != null && suffixes[i].equalsIgnoreCase(inSuffix))
                                        return i;
                                if (suffixes[i] != null && suffixes[i].equalsIgnoreCase(inSuffix))
                                        return i;
+                       }
                }
                return -1;
        }
                }
                return -1;
        }
index 187bb495c196ead68ad00b73a5926041267360e8..23ce909fc9dd8e9fd6089465659d980c315a7474 100644 (file)
@@ -200,6 +200,17 @@ public class BabelLoadFromFile extends BabelLoader
                return outerPanel;
        }
 
                return outerPanel;
        }
 
+       /**
+        * @return the suffix of the selected filename
+        */
+       private String getSelectedSuffix()
+       {
+               String filename = _inputFile.getName();
+               if (filename == null) {return "";}
+               int dotPos = filename.lastIndexOf('.');
+               return (dotPos > 0 ? filename.substring(dotPos) : "");
+       }
+
        /**
         * Initialise dialog
         */
        /**
         * Initialise dialog
         */
@@ -207,13 +218,16 @@ public class BabelLoadFromFile extends BabelLoader
        {
                _inputFileLabel.setText(_inputFile.getName());
                // Get suffix of filename and compare with previous one
        {
                _inputFileLabel.setText(_inputFile.getName());
                // Get suffix of filename and compare with previous one
-               String filename = _inputFile.getName();
-               int dotPos = filename.lastIndexOf('.');
-               String suffix = (dotPos > 0 ? filename.substring(dotPos) : null);
-               if (suffix != null && !suffix.equals(".") && (_lastSuffix == null || !suffix.equalsIgnoreCase(_lastSuffix)))
+               String suffix = getSelectedSuffix();
+               if (_lastSuffix == null || !suffix.equalsIgnoreCase(_lastSuffix))
                {
                {
-                       // New suffix chosen, so select first appropriate format (if any)
+                       // New suffix has been chosen, so select first appropriate format (if any)
                        int selIndex = BabelFileFormats.getIndexForFileSuffix(suffix);
                        int selIndex = BabelFileFormats.getIndexForFileSuffix(suffix);
+                       if (selIndex < 0)
+                       {
+                               // Use the previous one from the Config (if any)
+                               selIndex = Config.getConfigInt(Config.KEY_IMPORT_FILE_FORMAT);
+                       }
                        if (selIndex >= 0) {
                                _formatDropdown.setSelectedIndex(selIndex);
                        }
                        if (selIndex >= 0) {
                                _formatDropdown.setSelectedIndex(selIndex);
                        }
@@ -229,5 +243,12 @@ public class BabelLoadFromFile extends BabelLoader
                // Save the filter string, clear it if it's now blank
                final String filter = _filterPanel.getFilterString();
                Config.setConfigString(Config.KEY_GPSBABEL_FILTER, filter);
                // Save the filter string, clear it if it's now blank
                final String filter = _filterPanel.getFilterString();
                Config.setConfigString(Config.KEY_GPSBABEL_FILTER, filter);
+
+               // Check if there is a standard file type for the selected suffix
+               int selIndex = BabelFileFormats.getIndexForFileSuffix(getSelectedSuffix());
+               // If there is none, then get the index which the user chose and set in the Config
+               if (selIndex < 0) {
+                       Config.setConfigInt(Config.KEY_IMPORT_FILE_FORMAT, _formatDropdown.getSelectedIndex());
+               }
        }
 }
        }
 }
index 93303b205e0932bf640aceb56e4fc9cfad6ac75f..b9dd6c0ffbc995d063328c457c3e7abac65e3738 100644 (file)
@@ -1,5 +1,5 @@
-GpsPrune version 16
-===================
+GpsPrune version 16.3
+=====================
 
 GpsPrune is an application for viewing, editing and managing coordinate data from GPS systems,
 including format conversion, charting and photo correlation.
 
 GpsPrune is an application for viewing, editing and managing coordinate data from GPS systems,
 including format conversion, charting and photo correlation.
@@ -17,7 +17,7 @@ Running
 =======
 
 To run GpsPrune from the jar file, simply call it from a command prompt or shell:
 =======
 
 To run GpsPrune from the jar file, simply call it from a command prompt or shell:
-   java -jar gpsprune_16.jar
+   java -jar gpsprune_16.3.jar
 
 If the jar file is saved in a different directory, you will need to include the path.
 Depending on your system settings, you may be able to click or double-click on the jar file
 
 If the jar file is saved in a different directory, you will need to include the path.
 Depending on your system settings, you may be able to click or double-click on the jar file
@@ -25,11 +25,36 @@ in a file manager window to execute it.  A shortcut, menu item, alias, desktop i
 or other link can of course be made should you wish.
 
 To specify a language other than the default, use an additional parameter, eg:
 or other link can of course be made should you wish.
 
 To specify a language other than the default, use an additional parameter, eg:
-   java -jar gpsprune_16.jar --lang=DE
+   java -jar gpsprune_16.3.jar --lang=DE
 
 
 
 
-New with version 16
+New with version 16.3
 =====================
 =====================
+The following fixes were added since version 16.2:
+  - Fix for gpx caching of points which failed to load
+  - Additional newlines / tabs in gpx export
+  - API key for openweathermap.org
+  - Improvements to 3d terrain reflections
+  - Additional translations
+
+New with version 16.2
+=====================
+The following fixes were added since version 16.1:
+  - Fix for Gpx-slicing UTF8 files
+  - Conversion of sunrise/sunset times to local timezone
+  - Removal of Cloudmade maps
+  - Additional translations
+
+New with version 16.1
+=====================
+The following fixes were added since version 16:
+  - Caching of terrain information for three-dimensional views
+  - Additional translations
+  - Improved void filling by interpolation
+  - Remembering file type of imported files
+
+New with version 16
+===================
 The following features were added since version 15:
   - Extend povray output using terrain and/or map image
   - Extend java3d output using terrain and/or map image
 The following features were added since version 15:
   - Extend povray output using terrain and/or map image
   - Extend java3d output using terrain and/or map image
index 5c74a7a3894d22dd7c06d9e3e3bdb4b3fca7f1c3..672234fab4896b27e960189267631b6bda3e177b 100644 (file)
@@ -269,7 +269,7 @@ public class GpsSaver extends GenericFunction implements Runnable
                Process process = Runtime.getRuntime().exec(commands);
 
                String trackName = _trackNameField.getText();
                Process process = Runtime.getRuntime().exec(commands);
 
                String trackName = _trackNameField.getText();
-               if (trackName == null || trackName.equals("")) {trackName = "prune";}
+               if (trackName == null || trackName.equals("")) {trackName = "gpsprune";}
                // Generate the GPX file and send to the GPS
                OutputStreamWriter writer = new OutputStreamWriter(process.getOutputStream());
                boolean[] saveFlags = {true, true, true, true, false, true}; // export everything
                // Generate the GPX file and send to the GPS
                OutputStreamWriter writer = new OutputStreamWriter(process.getOutputStream());
                boolean[] saveFlags = {true, true, true, true, false, true}; // export everything
index a4ac1a7de2e72ade39734e7f0099fe6e14f5faca..1b2263bc8260d6dc49115f969de5e9c40be1ffcb 100644 (file)
@@ -11,7 +11,6 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStreamWriter;
 import java.io.Writer;
 import java.io.IOException;
 import java.io.OutputStreamWriter;
 import java.io.Writer;
-import java.nio.charset.Charset;
 
 import javax.swing.BorderFactory;
 import javax.swing.Box;
 
 import javax.swing.BorderFactory;
 import javax.swing.Box;
@@ -67,7 +66,6 @@ public class GpxExporter extends GenericFunction implements Runnable
        private JPanel _encodingsPanel = null;
        private JRadioButton _useSystemRadio = null, _forceUtf8Radio = null;
        private File _exportFile = null;
        private JPanel _encodingsPanel = null;
        private JRadioButton _useSystemRadio = null, _forceUtf8Radio = null;
        private File _exportFile = null;
-       private static String _systemEncoding = null;
 
        /** this program name */
        private static final String GPX_CREATOR = "GpsPrune v" + GpsPrune.VERSION_NUMBER + " activityworkshop.net";
 
        /** this program name */
        private static final String GPX_CREATOR = "GpsPrune v" + GpsPrune.VERSION_NUMBER + " activityworkshop.net";
@@ -99,15 +97,16 @@ public class GpxExporter extends GenericFunction implements Runnable
                        _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), true);
                        _dialog.setLocationRelativeTo(_parentFrame);
                        _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
                        _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), true);
                        _dialog.setLocationRelativeTo(_parentFrame);
                        _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
-                       _systemEncoding = getSystemEncoding();
                        _dialog.getContentPane().add(makeDialogComponents());
                        _dialog.pack();
                }
                _pointTypeSelector.init(_app.getTrackInfo());
                        _dialog.getContentPane().add(makeDialogComponents());
                        _dialog.pack();
                }
                _pointTypeSelector.init(_app.getTrackInfo());
-               _encodingsPanel.setVisible(!isSystemUtf8());
-               if (!isSystemUtf8()) {
+               _encodingsPanel.setVisible(!XmlUtils.isSystemUtf8());
+               if (!XmlUtils.isSystemUtf8())
+               {
+                       String systemEncoding = XmlUtils.getSystemEncoding();
                        _useSystemRadio.setText(I18nManager.getText("dialog.exportgpx.encoding.system")
                        _useSystemRadio.setText(I18nManager.getText("dialog.exportgpx.encoding.system")
-                               + " (" + (_systemEncoding == null ? "unknown" : _systemEncoding) + ")");
+                               + " (" + (systemEncoding == null ? "unknown" : systemEncoding) + ")");
                }
                _dialog.setVisible(true);
        }
                }
                _dialog.setVisible(true);
        }
@@ -148,7 +147,7 @@ public class GpxExporter extends GenericFunction implements Runnable
                mainPanel.add(checkPanel);
                // panel for selecting character encoding
                _encodingsPanel = new JPanel();
                mainPanel.add(checkPanel);
                // panel for selecting character encoding
                _encodingsPanel = new JPanel();
-               if (!isSystemUtf8())
+               if (!XmlUtils.isSystemUtf8())
                {
                        // only add this panel if system isn't utf8 (or can't be identified yet)
                        _encodingsPanel.setBorder(BorderFactory.createCompoundBorder(
                {
                        // only add this panel if system isn't utf8 (or can't be identified yet)
                        _encodingsPanel.setBorder(BorderFactory.createCompoundBorder(
@@ -384,6 +383,7 @@ public class GpxExporter extends GenericFunction implements Runnable
                                                if (!exportTimestamps) {
                                                        pointSource = stripTime(pointSource);
                                                }
                                                if (!exportTimestamps) {
                                                        pointSource = stripTime(pointSource);
                                                }
+                                               inWriter.write('\t');
                                                inWriter.write(pointSource);
                                                inWriter.write('\n');
                                        }
                                                inWriter.write(pointSource);
                                                inWriter.write('\n');
                                        }
@@ -402,10 +402,10 @@ public class GpxExporter extends GenericFunction implements Runnable
                                exportAudios, exportTimestamps, true, inGpxCachers, "<rtept", "\t<rte><number>1</number>\n",
                                null, "\t</rte>\n");
                        // Output all track points, if any
                                exportAudios, exportTimestamps, true, inGpxCachers, "<rtept", "\t<rte><number>1</number>\n",
                                null, "\t</rte>\n");
                        // Output all track points, if any
-                       String trackStart = "\t<trk><name>" + trackName + "</name><number>1</number><trkseg>\n";
+                       String trackStart = "\t<trk>\n\t\t<name>" + trackName + "</name>\n\t\t<number>1</number>\n\t\t<trkseg>\n";
                        numSaved += writeTrackPoints(inWriter, inInfo, exportSelection, exportTrackpoints, exportPhotos,
                                exportAudios, exportTimestamps, false, inGpxCachers, "<trkpt", trackStart,
                        numSaved += writeTrackPoints(inWriter, inInfo, exportSelection, exportTrackpoints, exportPhotos,
                                exportAudios, exportTimestamps, false, inGpxCachers, "<trkpt", trackStart,
-                               "\t</trkseg>\n\t<trkseg>\n", "\t</trkseg></trk>\n");
+                               "\t</trkseg>\n\t<trkseg>\n", "\t\t</trkseg>\n\t</trk>\n");
                }
 
                inWriter.write("</gpx>\n");
                }
 
                inWriter.write("</gpx>\n");
@@ -432,11 +432,13 @@ public class GpxExporter extends GenericFunction implements Runnable
                }
                if (inName != null && !inName.equals(""))
                {
                }
                if (inName != null && !inName.equals(""))
                {
-                       inWriter.write("\t\t<name>");
+                       if (inIsVersion1_1) {inWriter.write('\t');}
+                       inWriter.write("\t<name>");
                        inWriter.write(inName);
                        inWriter.write("</name>\n");
                }
                        inWriter.write(inName);
                        inWriter.write("</name>\n");
                }
-               inWriter.write("\t\t<desc>");
+               if (inIsVersion1_1) {inWriter.write('\t');}
+               inWriter.write("\t<desc>");
                inWriter.write(desc);
                inWriter.write("</desc>\n");
                if (inIsVersion1_1)
                inWriter.write(desc);
                inWriter.write("</desc>\n");
                if (inIsVersion1_1)
@@ -486,7 +488,9 @@ public class GpxExporter extends GenericFunction implements Runnable
                                        // get the source from the point (if any)
                                        String pointSource = getPointSource(inCachers, point);
                                        // Clear point source if it's the wrong type of point (eg changed from waypoint or route point)
                                        // get the source from the point (if any)
                                        String pointSource = getPointSource(inCachers, point);
                                        // Clear point source if it's the wrong type of point (eg changed from waypoint or route point)
-                                       if (pointSource != null && !pointSource.toLowerCase().startsWith(inPointTag)) {pointSource = null;}
+                                       if (pointSource != null && !pointSource.trim().toLowerCase().startsWith(inPointTag)) {
+                                               pointSource = null;
+                                       }
                                        if (pointSource != null || !inOnlyCopies)
                                        {
                                                // restart track segment if necessary
                                        if (pointSource != null || !inOnlyCopies)
                                        {
                                                // restart track segment if necessary
@@ -626,63 +630,10 @@ public class GpxExporter extends GenericFunction implements Runnable
         */
        private static String getXmlHeaderString(OutputStreamWriter inWriter)
        {
         */
        private static String getXmlHeaderString(OutputStreamWriter inWriter)
        {
-               return "<?xml version=\"1.0\" encoding=\"" + getEncoding(inWriter) + "\"?>\n";
+               return "<?xml version=\"1.0\" encoding=\"" + XmlUtils.getEncoding(inWriter) + "\"?>\n";
        }
 
 
        }
 
 
-       /**
-        * Get the default system encoding using a writer
-        * @param inWriter writer object
-        * @return string defining encoding
-        */
-       private static String getEncoding(OutputStreamWriter inWriter)
-       {
-               String encoding = inWriter.getEncoding();
-               try {
-                       encoding =  Charset.forName(encoding).name();
-               }
-               catch (Exception e) {} // ignore failure to find encoding
-               return encoding;
-       }
-
-
-       /**
-        * Use a temporary file to obtain the name of the default system encoding
-        * @return name of default system encoding, or null if write failed
-        */
-       private static String getSystemEncoding()
-       {
-               File tempFile = null;
-               String encoding = null;
-               try
-               {
-                       tempFile = File.createTempFile("prune", null);
-                       OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(tempFile));
-                       encoding = getEncoding(writer);
-                       writer.close();
-               }
-               catch (IOException e) {} // value stays null
-               // Delete temp file
-               if (tempFile != null && tempFile.exists()) {
-                       if (!tempFile.delete()) {
-                               System.err.println("Cannot delete temp file: " + tempFile.getAbsolutePath());
-                       }
-               }
-               // If writing failed (eg permissions) then just ask system for default
-               if (encoding == null) encoding = Charset.defaultCharset().name();
-               return encoding;
-       }
-
-       /**
-        * Creates temp file if necessary to check system encoding
-        * @return true if system uses UTF-8 by default
-        */
-       private static boolean isSystemUtf8()
-       {
-               if (_systemEncoding == null) _systemEncoding = getSystemEncoding();
-               return (_systemEncoding != null && _systemEncoding.toUpperCase().equals("UTF-8"));
-       }
-
        /**
         * Get the header string for the gpx tag
         * @param inCachers cacher list to ask for headers, if available
        /**
         * Get the header string for the gpx tag
         * @param inCachers cacher list to ask for headers, if available
@@ -790,24 +741,24 @@ public class GpxExporter extends GenericFunction implements Runnable
                boolean inExportPhoto, boolean inExportAudio)
                throws IOException
        {
                boolean inExportPhoto, boolean inExportAudio)
                throws IOException
        {
-               inWriter.write("\t\t<trkpt lat=\"");
+               inWriter.write("\t\t\t<trkpt lat=\"");
                inWriter.write(inPoint.getLatitude().output(Coordinate.FORMAT_DECIMAL_FORCE_POINT));
                inWriter.write("\" lon=\"");
                inWriter.write(inPoint.getLongitude().output(Coordinate.FORMAT_DECIMAL_FORCE_POINT));
                inWriter.write(inPoint.getLatitude().output(Coordinate.FORMAT_DECIMAL_FORCE_POINT));
                inWriter.write("\" lon=\"");
                inWriter.write(inPoint.getLongitude().output(Coordinate.FORMAT_DECIMAL_FORCE_POINT));
-               inWriter.write("\">");
+               inWriter.write("\">\n");
                // altitude
                if (inPoint.hasAltitude())
                {
                // altitude
                if (inPoint.hasAltitude())
                {
-                       inWriter.write("<ele>");
+                       inWriter.write("\t\t\t\t<ele>");
                        inWriter.write("" + inPoint.getAltitude().getStringValue(UnitSetLibrary.UNITS_METRES));
                        inWriter.write("" + inPoint.getAltitude().getStringValue(UnitSetLibrary.UNITS_METRES));
-                       inWriter.write("</ele>");
+                       inWriter.write("</ele>\n");
                }
                // timestamp if available (and selected)
                if (inPoint.hasTimestamp() && inTimestamps)
                {
                }
                // timestamp if available (and selected)
                if (inPoint.hasTimestamp() && inTimestamps)
                {
-                       inWriter.write("<time>");
+                       inWriter.write("\t\t\t\t<time>");
                        inWriter.write(inPoint.getTimestamp().getText(Timestamp.FORMAT_ISO_8601));
                        inWriter.write(inPoint.getTimestamp().getText(Timestamp.FORMAT_ISO_8601));
-                       inWriter.write("</time>");
+                       inWriter.write("</time>\n");
                }
                // photo, audio
                if (inPoint.getPhoto() != null && inExportPhoto) {
                }
                // photo, audio
                if (inPoint.getPhoto() != null && inExportPhoto) {
@@ -816,7 +767,7 @@ public class GpxExporter extends GenericFunction implements Runnable
                if (inPoint.getAudio() != null && inExportAudio) {
                        inWriter.write(makeMediaLink(inPoint.getAudio()));
                }
                if (inPoint.getAudio() != null && inExportAudio) {
                        inWriter.write(makeMediaLink(inPoint.getAudio()));
                }
-               inWriter.write("</trkpt>\n");
+               inWriter.write("\t\t\t</trkpt>\n");
        }
 
 
        }
 
 
@@ -867,6 +818,6 @@ public class GpxExporter extends GenericFunction implements Runnable
         */
        private static String stripTime(String inPointSource)
        {
         */
        private static String stripTime(String inPointSource)
        {
-               return inPointSource.replaceAll("<time>.*?</time>", "");
+               return inPointSource.replaceAll("[ \t]*<time>.*?</time>", "");
        }
 }
        }
 }
index 1f29d4a70bb075420db66a471ca7a9d7e730c28d..19e4485c66bf0e09ec576793804bdf88c4187591 100644 (file)
@@ -43,6 +43,8 @@ import tim.prune.gui.map.MapSource;
 import tim.prune.gui.map.MapSourceLibrary;
 import tim.prune.load.GenericFileFilter;
 import tim.prune.threedee.ImageDefinition;
 import tim.prune.gui.map.MapSourceLibrary;
 import tim.prune.load.GenericFileFilter;
 import tim.prune.threedee.ImageDefinition;
+import tim.prune.threedee.TerrainCache;
+import tim.prune.threedee.TerrainDefinition;
 import tim.prune.threedee.TerrainHelper;
 import tim.prune.threedee.ThreeDModel;
 
 import tim.prune.threedee.TerrainHelper;
 import tim.prune.threedee.ThreeDModel;
 
@@ -392,19 +394,29 @@ public class PovExporter extends Export3dFunction
                        if (useTerrain)
                        {
                                TerrainHelper terrainHelper = new TerrainHelper(_terrainPanel.getGridSize());
                        if (useTerrain)
                        {
                                TerrainHelper terrainHelper = new TerrainHelper(_terrainPanel.getGridSize());
-                               Track terrainTrack = terrainHelper.createGridTrack(_track);
-                               // Get the altitudes from SRTM for all the points in the track
-                               LookupSrtmFunction srtmLookup = (LookupSrtmFunction) FunctionLibrary.FUNCTION_LOOKUP_SRTM;
-                               srtmLookup.begin(terrainTrack);
-                               while (srtmLookup.isRunning())
+                               // See if there's a previously saved terrain track we can reuse
+                               TerrainDefinition terrainDef = new TerrainDefinition(_terrainPanel.getUseTerrain(), _terrainPanel.getGridSize());
+                               Track terrainTrack = TerrainCache.getTerrainTrack(_app.getCurrentDataStatus(), terrainDef);
+                               if (terrainTrack == null)
                                {
                                {
-                                       try {
-                                               Thread.sleep(750);  // just polling in a wait loop isn't ideal but simple
+                                       // Construct the terrain track according to these extents and the grid size
+                                       terrainTrack = terrainHelper.createGridTrack(_track);
+                                       // Get the altitudes from SRTM for all the points in the track
+                                       LookupSrtmFunction srtmLookup = (LookupSrtmFunction) FunctionLibrary.FUNCTION_LOOKUP_SRTM;
+                                       srtmLookup.begin(terrainTrack);
+                                       while (srtmLookup.isRunning())
+                                       {
+                                               try {
+                                                       Thread.sleep(750);  // just polling in a wait loop isn't ideal but simple
+                                               }
+                                               catch (InterruptedException e) {}
                                        }
                                        }
-                                       catch (InterruptedException e) {}
+                                       // Fix the voids
+                                       terrainHelper.fixVoids(terrainTrack);
+
+                                       // Store this back in the cache, maybe we'll need it again
+                                       TerrainCache.storeTerrainTrack(terrainTrack, _app.getCurrentDataStatus(), terrainDef);
                                }
                                }
-                               // Fix the voids
-                               terrainHelper.fixVoids(terrainTrack);
 
                                model.setTerrain(terrainTrack);
                                model.scale();
 
                                model.setTerrain(terrainTrack);
                                model.scale();
diff --git a/tim/prune/save/xml/ByteBuffer.java b/tim/prune/save/xml/ByteBuffer.java
new file mode 100644 (file)
index 0000000..67091e1
--- /dev/null
@@ -0,0 +1,88 @@
+package tim.prune.save.xml;
+
+import java.nio.charset.Charset;
+
+/**
+ * Class to collect the bytes from an input stream
+ * and turn them into a String
+ */
+public class ByteBuffer
+{
+       // Array of bytes
+       private byte[] _bytes = new byte[1024];
+       // Current position to append
+       private int _currPos = 0;
+       // Flag for recognising utf8 encoded streams
+       private boolean _streamUtf8 = false;
+       // Flag for whether system is utf8 or not
+       private final boolean _systemUtf8 = XmlUtils.isSystemUtf8();
+
+       /**
+        * Append the given byte to the buffer
+        * @param inB byte to append
+        */
+       public void appendByte(byte inB)
+       {
+               // Resize array if necessary
+               if (_currPos >= _bytes.length)
+               {
+                       byte[] bigger = new byte[_bytes.length * 2];
+                       System.arraycopy(_bytes, 0, bigger, 0, _bytes.length);
+                       _bytes = bigger;
+               }
+               // Append byte and increment counter
+               _bytes[_currPos] = inB;
+               _currPos++;
+       }
+
+       /**
+        * Clear the buffer and reset
+        */
+       public void clear()
+       {
+               _currPos = 0;
+               // Reduce size back to default if it's got too big
+               if (_bytes.length > 5000) {
+                       _bytes = new byte[1024];
+               }
+       }
+
+       /**
+        * Set the flag that this stream is encoded with utf8
+        */
+       public void setEncodingUtf8() {
+               _streamUtf8 = true;
+       }
+
+       /**
+        * @return contents of buffer as a String
+        */
+       public String toString()
+       {
+               // Sometimes the encoding of the read file isn't the default encoding of the system
+               if (_streamUtf8 && !_systemUtf8)
+               {
+                       return new String(_bytes, 0, _currPos, Charset.forName("UTF-8"));
+               }
+               // Otherwise just use system encoding
+               return new String(_bytes, 0, _currPos);
+       }
+
+       /**
+        * Look for the given character sequence in the last characters read
+        * @param inChars sequence to look for
+        * @return true if sequence found
+        */
+       public boolean foundSequence(char[] inChars)
+       {
+               final int numChars = inChars.length;
+               if (_currPos < numChars) {return false;}
+               for (int i=0; i<numChars; i++)
+               {
+                       char searchChar = inChars[numChars - 1 - i];
+                       char sourceChar = (char) _bytes[_currPos - 1 - i];
+                       if (searchChar != sourceChar) {return false;}
+               }
+               return true;
+       }
+}
index 2c3204dab3fbee01e698c669d905a12b93e737ff..9ab8552e771cef536d8e942c17948f6d98fe3e65 100644 (file)
@@ -72,9 +72,19 @@ public class GpxCacher implements TagReceiver
                if (_headerString == null) {
                        _headerString = inTag;
                }
                if (_headerString == null) {
                        _headerString = inTag;
                }
-               else {
-                       _strings[_pointNum] = inTag;
-                       _pointNum++;
+               else if (_strings != null)
+               {
+                       if (_pointNum < _strings.length)
+                       {
+                               _strings[_pointNum] = inTag;
+                               _pointNum++;
+                       }
+                       else
+                       {
+                               // _pointNum has got too high for the strings array
+                               // This means the cacher has failed, probably by invalid points - need to give up caching here
+                               _strings = null;
+                       }
                }
        }
 
                }
        }
 
@@ -95,7 +105,7 @@ public class GpxCacher implements TagReceiver
        public String getSourceString(DataPoint inPoint)
        {
                int index = _sourceInfo.getIndex(inPoint);
        public String getSourceString(DataPoint inPoint)
        {
                int index = _sourceInfo.getIndex(inPoint);
-               if (index >= 0) {
+               if (_strings != null && index >= 0 && index < _strings.length) {
                        return _strings[index];
                }
                return null;
                        return _strings[index];
                }
                return null;
index efc58b488666a7ee089dee174bc8f22668ff9dee..d18d7607656533d6aacbae5c599daa17df6076fe 100644 (file)
@@ -12,8 +12,6 @@ public class GpxSlicer
 {
        /** listener to receive tags */
        private TagReceiver _receiver = null;
 {
        /** listener to receive tags */
        private TagReceiver _receiver = null;
-       /** string builder for copying source xml */
-       private StringBuilder _builder = null;
 
        // character sequences for start and end of tags
        private static final char[] GPX_START = "<gpx".toCharArray();
 
        // character sequences for start and end of tags
        private static final char[] GPX_START = "<gpx".toCharArray();
@@ -27,7 +25,6 @@ public class GpxSlicer
        private static final char[] CDATA_START = "<![CDATA[".toCharArray();
        private static final char[] CDATA_END = "]]>".toCharArray();
 
        private static final char[] CDATA_START = "<![CDATA[".toCharArray();
        private static final char[] CDATA_END = "]]>".toCharArray();
 
-
        /**
         * Constructor
         * @param inReceiver listener for tags
        /**
         * Constructor
         * @param inReceiver listener for tags
@@ -43,7 +40,8 @@ public class GpxSlicer
         */
        public void slice(InputStream inStream)
        {
         */
        public void slice(InputStream inStream)
        {
-               _builder = new StringBuilder(100);
+               StringBuffer beginBuffer = new StringBuffer(200);
+               ByteBuffer byteBuffer = new ByteBuffer();
                boolean insideTag = false;
                boolean insideCdata = false;
                char[] endTag = null;
                boolean insideTag = false;
                boolean insideCdata = false;
                char[] endTag = null;
@@ -53,37 +51,49 @@ public class GpxSlicer
                {
                        while ((b = inStream.read()) >= 0)
                        {
                {
                        while ((b = inStream.read()) >= 0)
                        {
-                               if (!insideTag && !insideCdata) {
-                                       if (b == '<') _builder.setLength(0);
-                               }
                                // copy character
                                // copy character
-                               _builder.append((char)b);
+                               byteBuffer.appendByte((byte) b);
+                               // clear buffer if necessary
+                               if (!insideTag && !insideCdata && (b == '>' || b == '\n'))
+                               {
+                                       byteBuffer.clear();
+                                       continue;
+                               }
+                               // if we're still at the beginning, copy to the begin buffer as well
+                               if (beginBuffer != null) {beginBuffer.append((char) b);}
 
                                if (insideCdata) {
                                        // Just look for end of cdata block
 
                                if (insideCdata) {
                                        // Just look for end of cdata block
-                                       if (foundSequence(CDATA_END)) {insideCdata = false;}
+                                       if (byteBuffer.foundSequence(CDATA_END)) {insideCdata = false;}
                                }
                                else
                                {
                                        if (!insideTag)
                                        {
                                                // Look for start of one of the tags
                                }
                                else
                                {
                                        if (!insideTag)
                                        {
                                                // Look for start of one of the tags
-                                               if (!foundHeader && foundSequence(GPX_START)) {
+                                               if (!foundHeader && byteBuffer.foundSequence(GPX_START))
+                                               {
                                                        insideTag = true;
                                                        foundHeader = true;
                                                        endTag = GPX_END;
                                                        insideTag = true;
                                                        foundHeader = true;
                                                        endTag = GPX_END;
+                                                       // Check begin buffer for utf8 encoding
+                                                       if (beginBuffer != null && beginBuffer.toString().toLowerCase().indexOf("encoding=\"utf-8\"") > 0)
+                                                       {
+                                                               byteBuffer.setEncodingUtf8();
+                                                       }
+                                                       beginBuffer = null; // don't need it any more
                                                }
                                                else if (b == 't')
                                                {
                                                }
                                                else if (b == 't')
                                                {
-                                                       if (foundSequence(TRKPT_START)) {
+                                                       if (byteBuffer.foundSequence(TRKPT_START)) {
                                                                insideTag = true;
                                                                endTag = TRKPT_END;
                                                        }
                                                                insideTag = true;
                                                                endTag = TRKPT_END;
                                                        }
-                                                       else if (foundSequence(WPT_START)) {
+                                                       else if (byteBuffer.foundSequence(WPT_START)) {
                                                                insideTag = true;
                                                                endTag = WPT_END;
                                                        }
                                                                insideTag = true;
                                                                endTag = WPT_END;
                                                        }
-                                                       else if (foundSequence(RTEPT_START)) {
+                                                       else if (byteBuffer.foundSequence(RTEPT_START)) {
                                                                insideTag = true;
                                                                endTag = RTEPT_END;
                                                        }
                                                                insideTag = true;
                                                                endTag = RTEPT_END;
                                                        }
@@ -92,37 +102,21 @@ public class GpxSlicer
                                        else
                                        {
                                                // Look for end of found tag
                                        else
                                        {
                                                // Look for end of found tag
-                                               if (foundSequence(endTag)) {
-                                                       _receiver.reportTag(_builder.toString());
-                                                       _builder.setLength(0);
+                                               if (byteBuffer.foundSequence(endTag))
+                                               {
+                                                       String tag = byteBuffer.toString();
+                                                       _receiver.reportTag(tag);
+                                                       byteBuffer.clear();
                                                        insideTag = false;
                                                }
                                        }
                                        // Look for start of cdata block
                                                        insideTag = false;
                                                }
                                        }
                                        // Look for start of cdata block
-                                       if (foundSequence(CDATA_START)) {insideCdata = true;}
+                                       if (byteBuffer.foundSequence(CDATA_START)) {
+                                               insideCdata = true;
+                                       }
                                }
                        }
                }
                catch (IOException e) {} // ignore
        }
                                }
                        }
                }
                catch (IOException e) {} // ignore
        }
-
-       /**
-        * Look for the given character sequence in the last characters read
-        * @param inChars sequence to look for
-        * @return true if sequence found
-        */
-       private boolean foundSequence(char[] inChars)
-       {
-               final int numChars = inChars.length;
-               final int bufflen = _builder.length();
-               if (bufflen < numChars) {return false;}
-               for (int i=0; i<numChars; i++)
-               {
-                       char searchChar = inChars[numChars - 1 - i];
-                       char sourceChar = _builder.charAt(bufflen - 1 - i);
-                       if (searchChar != sourceChar) {return false;}
-                       //if (Character.toLowerCase(searchChar) != Character.toLowerCase(sourceChar)) {return false;}
-               }
-               return true;
-       }
 }
 }
index a4f9caec11704a46dcd56fe3d22bde4922a49f09..dc8284c30ea90d4586b0cdec70c72c6102346225 100644 (file)
@@ -1,5 +1,11 @@
 package tim.prune.save.xml;
 
 package tim.prune.save.xml;
 
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.nio.charset.Charset;
+
 /**
  * Collection of utility functions for handling XML
  */
 /**
  * Collection of utility functions for handling XML
  */
@@ -9,6 +15,8 @@ public abstract class XmlUtils
        private static final String CDATA_START = "<![CDATA[";
        /** End of Cdata sequence */
        private static final String CDATA_END = "]]>";
        private static final String CDATA_START = "<![CDATA[";
        /** End of Cdata sequence */
        private static final String CDATA_END = "]]>";
+       /** Cached copy of system encoding string */
+       private static String _systemEncoding = null;
 
        /**
         * Fix the CDATA blocks in the given String to give valid xml
 
        /**
         * Fix the CDATA blocks in the given String to give valid xml
@@ -34,4 +42,68 @@ public abstract class XmlUtils
                }
                return CDATA_START + result + CDATA_END;
        }
                }
                return CDATA_START + result + CDATA_END;
        }
+
+
+       /**
+        * @return true if system uses UTF-8 by default
+        */
+       public static boolean isSystemUtf8()
+       {
+               String systemEncoding = getSystemEncoding();
+               return (systemEncoding != null && systemEncoding.toUpperCase().equals("UTF-8"));
+       }
+
+       /**
+        * @return name of the system's character encoding
+        */
+       public static String getSystemEncoding()
+       {
+               if (_systemEncoding == null) {
+                       _systemEncoding = determineSystemEncoding();
+               }
+               return _systemEncoding;
+       }
+
+       /**
+        * Use a temporary file to obtain the name of the default system encoding
+        * @return name of default system encoding, or null if write failed
+        */
+       private static String determineSystemEncoding()
+       {
+               File tempFile = null;
+               String encoding = null;
+               try
+               {
+                       tempFile = File.createTempFile("gpsprune", null);
+                       OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(tempFile));
+                       encoding = getEncoding(writer);
+                       writer.close();
+               }
+               catch (IOException e) {} // value stays null
+               // Delete temp file
+               if (tempFile != null && tempFile.exists()) {
+                       if (!tempFile.delete()) {
+                               System.err.println("Cannot delete temp file: " + tempFile.getAbsolutePath());
+                       }
+               }
+               // If writing failed (eg permissions) then just ask system for default
+               if (encoding == null) encoding = Charset.defaultCharset().name();
+               return encoding;
+       }
+
+
+       /**
+        * Get the default system encoding using a writer
+        * @param inWriter writer object
+        * @return string defining encoding
+        */
+       public static String getEncoding(OutputStreamWriter inWriter)
+       {
+               String encoding = inWriter.getEncoding();
+               try {
+                       encoding =  Charset.forName(encoding).name();
+               }
+               catch (Exception e) {} // ignore failure to find encoding
+               return encoding;
+       }
 }
 }
index ba1ed1530c282e5607d24816bc391f72d68d48c7..fdda0fcc4f53de305e4177866ea8132c09249a97 100644 (file)
@@ -27,9 +27,9 @@ import javax.media.j3d.QuadArray;
 import javax.media.j3d.Shape3D;
 import javax.media.j3d.Text3D;
 import javax.media.j3d.Texture;
 import javax.media.j3d.Shape3D;
 import javax.media.j3d.Text3D;
 import javax.media.j3d.Texture;
+import javax.media.j3d.TextureAttributes;
 import javax.media.j3d.Transform3D;
 import javax.media.j3d.TransformGroup;
 import javax.media.j3d.Transform3D;
 import javax.media.j3d.TransformGroup;
-import javax.media.j3d.TriangleStripArray;
 import javax.swing.JButton;
 import javax.swing.JFrame;
 import javax.swing.JOptionPane;
 import javax.swing.JButton;
 import javax.swing.JFrame;
 import javax.swing.JOptionPane;
@@ -41,6 +41,7 @@ import javax.vecmath.Point3f;
 import javax.vecmath.TexCoord2f;
 import javax.vecmath.Vector3d;
 
 import javax.vecmath.TexCoord2f;
 import javax.vecmath.Vector3d;
 
+import tim.prune.DataStatus;
 import tim.prune.FunctionLibrary;
 import tim.prune.I18nManager;
 import tim.prune.data.Track;
 import tim.prune.FunctionLibrary;
 import tim.prune.I18nManager;
 import tim.prune.data.Track;
@@ -53,6 +54,8 @@ import tim.prune.save.MapGrouter;
 import com.sun.j3d.utils.behaviors.vp.OrbitBehavior;
 import com.sun.j3d.utils.geometry.Box;
 import com.sun.j3d.utils.geometry.Cylinder;
 import com.sun.j3d.utils.behaviors.vp.OrbitBehavior;
 import com.sun.j3d.utils.geometry.Box;
 import com.sun.j3d.utils.geometry.Cylinder;
+import com.sun.j3d.utils.geometry.GeometryInfo;
+import com.sun.j3d.utils.geometry.NormalGenerator;
 import com.sun.j3d.utils.geometry.Sphere;
 import com.sun.j3d.utils.image.TextureLoader;
 import com.sun.j3d.utils.universe.SimpleUniverse;
 import com.sun.j3d.utils.geometry.Sphere;
 import com.sun.j3d.utils.image.TextureLoader;
 import com.sun.j3d.utils.universe.SimpleUniverse;
@@ -72,6 +75,7 @@ public class Java3DWindow implements ThreeDWindow
        private ImageDefinition _imageDefinition = null;
        private GroutedImage _baseImage = null;
        private TerrainDefinition _terrainDefinition = null;
        private ImageDefinition _imageDefinition = null;
        private GroutedImage _baseImage = null;
        private TerrainDefinition _terrainDefinition = null;
+       private DataStatus _dataStatus = null;
 
        /** only prompt about big track size once */
        private static boolean TRACK_SIZE_WARNING_GIVEN = false;
 
        /** only prompt about big track size once */
        private static boolean TRACK_SIZE_WARNING_GIVEN = false;
@@ -134,6 +138,14 @@ public class Java3DWindow implements ThreeDWindow
                _terrainDefinition = inDefinition;
        }
 
                _terrainDefinition = inDefinition;
        }
 
+       /**
+        * Set the current data status
+        */
+       public void setDataStatus(DataStatus inStatus)
+       {
+               _dataStatus = inStatus;
+       }
+
        /**
         * Show the window
         */
        /**
         * Show the window
         */
@@ -331,24 +343,31 @@ public class Java3DWindow implements ThreeDWindow
 
                if (showTerrain)
                {
 
                if (showTerrain)
                {
-                       // TODO: Is it maybe possible to cache the last terrainTrack?
-                       //       (if the dataTrack and the resolution haven't changed)
-                       // Construct the terrain track according to these extents and the grid size
                        TerrainHelper terrainHelper = new TerrainHelper(_terrainDefinition.getGridSize());
                        TerrainHelper terrainHelper = new TerrainHelper(_terrainDefinition.getGridSize());
-                       Track terrainTrack = terrainHelper.createGridTrack(_track);
-                       // Get the altitudes from SRTM for all the points in the track
-                       LookupSrtmFunction srtmLookup = (LookupSrtmFunction) FunctionLibrary.FUNCTION_LOOKUP_SRTM;
-                       srtmLookup.begin(terrainTrack);
-                       while (srtmLookup.isRunning())
+                       // See if there's a previously saved terrain track we can reuse
+                       Track terrainTrack = TerrainCache.getTerrainTrack(_dataStatus, _terrainDefinition);
+                       if (terrainTrack == null)
                        {
                        {
-                               try {
-                                       Thread.sleep(750);  // just polling in a wait loop isn't ideal but simple
+                               // Construct the terrain track according to these extents and the grid size
+                               terrainTrack = terrainHelper.createGridTrack(_track);
+                               // Get the altitudes from SRTM for all the points in the track
+                               LookupSrtmFunction srtmLookup = (LookupSrtmFunction) FunctionLibrary.FUNCTION_LOOKUP_SRTM;
+                               srtmLookup.begin(terrainTrack);
+                               while (srtmLookup.isRunning())
+                               {
+                                       try {
+                                               Thread.sleep(750);  // just polling in a wait loop isn't ideal but simple
+                                       }
+                                       catch (InterruptedException e) {}
                                }
                                }
-                               catch (InterruptedException e) {}
-                       }
 
 
-                       // Fix the voids
-                       terrainHelper.fixVoids(terrainTrack);
+                               // Fix the voids
+                               terrainHelper.fixVoids(terrainTrack);
+
+                               // Store this back in the cache, maybe we'll need it again
+                               TerrainCache.storeTerrainTrack(terrainTrack, _dataStatus, _terrainDefinition);
+                       }
+                       // else System.out.println("Yay - reusing the cached track!");
 
                        // Give the terrain definition to the _model as well
                        _model.setTerrain(terrainTrack);
 
                        // Give the terrain definition to the _model as well
                        _model.setTerrain(terrainTrack);
@@ -575,11 +594,8 @@ public class Java3DWindow implements ThreeDWindow
        {
                final int numNodes = inHelper.getGridSize();
                final int RESULT_SIZE = numNodes * (numNodes * 2 - 2);
        {
                final int numNodes = inHelper.getGridSize();
                final int RESULT_SIZE = numNodes * (numNodes * 2 - 2);
-               final int GEOMETRY_COLOURING_TYPE = (inBaseImage == null ? GeometryArray.COLOR_3 : GeometryArray.TEXTURE_COORDINATE_2);
-
                int[] stripData = inHelper.getStripLengths();
                int[] stripData = inHelper.getStripLengths();
-               TriangleStripArray tsa = new TriangleStripArray(RESULT_SIZE, GeometryArray.COORDINATES | GEOMETRY_COLOURING_TYPE,
-                       stripData);
+
                // Get the scaled terrainTrack coordinates (or just heights) from the model
                final int nSquared = numNodes * numNodes;
                Point3d[] rawPoints = new Point3d[nSquared];
                // Get the scaled terrainTrack coordinates (or just heights) from the model
                final int nSquared = numNodes * numNodes;
                Point3d[] rawPoints = new Point3d[nSquared];
@@ -590,23 +606,37 @@ public class Java3DWindow implements ThreeDWindow
                                Math.max(height, 0.05), // make sure it's above the box
                                -inModel.getScaledTerrainVertValue(i) * MODEL_SCALE_FACTOR);
                }
                                Math.max(height, 0.05), // make sure it's above the box
                                -inModel.getScaledTerrainVertValue(i) * MODEL_SCALE_FACTOR);
                }
-               tsa.setCoordinates(0, inHelper.getTerrainCoordinates(rawPoints));
+
+               GeometryInfo gi = new GeometryInfo(GeometryInfo.TRIANGLE_STRIP_ARRAY);
+               gi.setCoordinates(inHelper.getTerrainCoordinates(rawPoints));
+               gi.setStripCounts(stripData);
 
                Appearance tAppearance = new Appearance();
                if (inBaseImage != null)
                {
 
                Appearance tAppearance = new Appearance();
                if (inBaseImage != null)
                {
-                       tsa.setTextureCoordinates(0, 0, inHelper.getTextureCoordinates());
+                       gi.setTextureCoordinateParams(1,  2); // one coord set of two dimensions
+                       gi.setTextureCoordinates(0, inHelper.getTextureCoordinates());
                        Texture mapImage = new TextureLoader(inBaseImage.getImage()).getTexture();
                        tAppearance.setTexture(mapImage);
                        Texture mapImage = new TextureLoader(inBaseImage.getImage()).getTexture();
                        tAppearance.setTexture(mapImage);
+                       TextureAttributes texAttr = new TextureAttributes();
+                       texAttr.setTextureMode(TextureAttributes.MODULATE);
+                       tAppearance.setTextureAttributes(texAttr);
                }
                else
                {
                        Color3f[] colours = new Color3f[RESULT_SIZE];
                        Color3f terrainColour = new Color3f(0.1f, 0.2f, 0.2f);
                        for (int i=0; i<RESULT_SIZE; i++) {colours[i] = terrainColour;}
                }
                else
                {
                        Color3f[] colours = new Color3f[RESULT_SIZE];
                        Color3f terrainColour = new Color3f(0.1f, 0.2f, 0.2f);
                        for (int i=0; i<RESULT_SIZE; i++) {colours[i] = terrainColour;}
-                       tsa.setColors(0, colours);
+                       gi.setColors(colours);
                }
                }
-               return new Shape3D(tsa, tAppearance);
+               new NormalGenerator().generateNormals(gi);
+               Material terrnMat = new Material(new Color3f(0.4f, 0.4f, 0.4f), // ambient colour
+                       new Color3f(0f, 0f, 0f), // emissive (none)
+                       new Color3f(0.8f, 0.8f, 0.8f), // diffuse
+                       new Color3f(0.2f, 0.2f, 0.2f), //specular
+                       30f); // shinyness
+               tAppearance.setMaterial(terrnMat);
+               return new Shape3D(gi.getGeometryArray(), tAppearance);
        }
 
        /**
        }
 
        /**
diff --git a/tim/prune/threedee/TerrainCache.java b/tim/prune/threedee/TerrainCache.java
new file mode 100644 (file)
index 0000000..5f5733f
--- /dev/null
@@ -0,0 +1,57 @@
+package tim.prune.threedee;
+
+import tim.prune.DataStatus;
+import tim.prune.data.Track;
+
+/**
+ * This abstract class acts as a singleton to store a single
+ * terrain model (as a Track) for a given data status and terrain definition.
+ * When the data or the definition changes, this track becomes invalid.
+ */
+public abstract class TerrainCache
+{
+       /** The data status at the time this terrain was generated */
+       private static DataStatus _dataStatus = null;
+       /** The definition (grid size) for this terrain */
+       private static TerrainDefinition _terrainDef = null;
+       /** The generated grid of points with altitudes */
+       private static Track _terrainTrack = null;
+
+
+       /**
+        * Get the stored terrain track if it's still valid
+        * @param inCurrStatus current data status
+        * @param inTerrainDef currently selected terrain definition
+        * @return stored terrain track if it's valid, null otherwise
+        */
+       public static Track getTerrainTrack(DataStatus inCurrStatus, TerrainDefinition inTerrainDef)
+       {
+               if (_dataStatus == null || _terrainDef == null || _terrainTrack == null)
+               {
+                       return null; // nothing stored
+               }
+               if (inCurrStatus == null || inTerrainDef == null || !inTerrainDef.getUseTerrain())
+               {
+                       return null; // nonsense requested
+               }
+               if (inCurrStatus.hasDataChanged(_dataStatus) || !inTerrainDef.equals(_terrainDef))
+               {
+                       return null; // stored track is out of date
+               }
+               // we have a match
+               return _terrainTrack;
+       }
+
+       /**
+        * Now that a terrain track has been generated, store it for possible reuse
+        * @param inTrack terrain track to store
+        * @param inCurrStatus current data status
+        * @param inTerrainDef terrain definition
+        */
+       public static void storeTerrainTrack(Track inTrack, DataStatus inCurrStatus, TerrainDefinition inTerrainDef)
+       {
+               _terrainTrack = inTrack;
+               _dataStatus = inCurrStatus;
+               _terrainDef = inTerrainDef;
+       }
+}
index 0b35670aaa61d55042b1e20e20dac200fdf481d0..d6cf3854f9525dc2fbf1c6754ad3dfa20ea488c1 100644 (file)
@@ -51,4 +51,18 @@ public class TerrainDefinition
        public int getGridSize() {
                return _gridSize;
        }
        public int getGridSize() {
                return _gridSize;
        }
+
+       @Override
+       /**
+        * Compare two TerrainDefinitions to see if they're equal
+        */
+       public boolean equals(Object obj)
+       {
+               if (obj == null || !(obj instanceof TerrainDefinition)) {
+                       return false;
+               }
+               TerrainDefinition other = (TerrainDefinition) obj;
+               return _useTerrain == other._useTerrain
+                       && _gridSize == other._gridSize;
+       }
 }
 }
index 71bc196a46dce7c8c4658dfb23490ab8f23fc323..0be2216cdf592384e95feb5c5ac34add99453b69 100644 (file)
@@ -196,12 +196,13 @@ public class TerrainHelper
        {
                int numVoids = countVoids(inTerrainTrack);
                if (numVoids == 0) {return;}
        {
                int numVoids = countVoids(inTerrainTrack);
                if (numVoids == 0) {return;}
-               // System.out.println("Starting to fix, num voids = " + numVoids);
+               //System.out.println("Starting to fix, num voids = " + numVoids);
                // Fix the holes which are surrounded on all four sides by non-holes
                fixSingleHoles(inTerrainTrack);
                // Fix the holes which are surrounded on all four sides by non-holes
                fixSingleHoles(inTerrainTrack);
-               // System.out.println("Fixed single holes, now num voids = " + countVoids(inTerrainTrack));
+               //System.out.println("Fixed single holes, now num voids = " + countVoids(inTerrainTrack));
                // Maybe there is something to do in the corners?
                // Maybe there is something to do in the corners?
-               fixCorners(inTerrainTrack);
+               fixCornersAndEdges(inTerrainTrack);
+               //System.out.println("Fixed corners, now num voids = " + countVoids(inTerrainTrack));
                // Now fix the bigger holes, which should fix everything left
                fixBiggerHoles(inTerrainTrack);
                final int numHolesLeft = countVoids(inTerrainTrack);
                // Now fix the bigger holes, which should fix everything left
                fixBiggerHoles(inTerrainTrack);
                final int numHolesLeft = countVoids(inTerrainTrack);
@@ -216,6 +217,21 @@ public class TerrainHelper
         */
        private static int countVoids(Track inTerrainTrack)
        {
         */
        private static int countVoids(Track inTerrainTrack)
        {
+               // DEBUG: Show state of voids first
+//             final int gridSize = (int) Math.sqrt(inTerrainTrack.getNumPoints());
+//             StringBuilder sb = new StringBuilder();
+//             for (int i=0; i<inTerrainTrack.getNumPoints(); i++)
+//             {
+//                     if ((i%gridSize) == 0) sb.append('\n');
+//                     if (inTerrainTrack.getPoint(i).hasAltitude()) {
+//                             sb.append('A');
+//                     } else {
+//                             sb.append(' ');
+//                     }
+//             }
+//             System.out.println("Voids:" + sb.toString());
+               // END DEBUG
+
                int numVoids = 0;
                if (inTerrainTrack != null)
                {
                int numVoids = 0;
                if (inTerrainTrack != null)
                {
@@ -271,7 +287,7 @@ public class TerrainHelper
 
                                                double altitude = 0.0;
                                                if (pll != null && pll.hasAltitude() && prr != null && prr.hasAltitude()
 
                                                double altitude = 0.0;
                                                if (pll != null && pll.hasAltitude() && prr != null && prr.hasAltitude()
-                                                       && puu != null && puu.hasAltitude() && pdd != null & pdd.hasAltitude())
+                                                       && puu != null && puu.hasAltitude() && pdd != null && pdd.hasAltitude())
                                                {
                                                        // Use the double-neighbours too to take into account the gradients
                                                        altitude = (
                                                {
                                                        // Use the double-neighbours too to take into account the gradients
                                                        altitude = (
@@ -304,15 +320,19 @@ public class TerrainHelper
        }
 
        /**
        }
 
        /**
-        * Try to fix the corners, if they're blank
+        * Try to fix the corners and edges, if they're blank
         * @param inTerrainTrack terrain track
         */
         * @param inTerrainTrack terrain track
         */
-       private void fixCorners(Track inTerrainTrack)
+       private void fixCornersAndEdges(Track inTerrainTrack)
        {
                fixCorner(inTerrainTrack, 0, 1, 1);
                fixCorner(inTerrainTrack, _gridSize-1, -1, 1);
                fixCorner(inTerrainTrack, (_gridSize-1)*_gridSize, 1, -1);
                fixCorner(inTerrainTrack, _gridSize*_gridSize-1, -1, -1);
        {
                fixCorner(inTerrainTrack, 0, 1, 1);
                fixCorner(inTerrainTrack, _gridSize-1, -1, 1);
                fixCorner(inTerrainTrack, (_gridSize-1)*_gridSize, 1, -1);
                fixCorner(inTerrainTrack, _gridSize*_gridSize-1, -1, -1);
+               fixEdge(inTerrainTrack, 0, 1);
+               fixEdge(inTerrainTrack, _gridSize-1, _gridSize);
+               fixEdge(inTerrainTrack, (_gridSize-1)*_gridSize, -_gridSize);
+               fixEdge(inTerrainTrack, _gridSize*_gridSize-1, -1);
        }
 
        /**
        }
 
        /**
@@ -355,6 +375,40 @@ public class TerrainHelper
                }
        }
 
                }
        }
 
+       /**
+        * Fix any holes found in the specified edge
+        * @param inTerrainTrack terrain track
+        * @param inCornerIndex index of corner to start from
+        * @param inInc increment along edge
+        */
+       private void fixEdge(Track inTerrainTrack, int inCornerIndex, int inInc)
+       {
+               int prevIndexWithAlt = -1;
+               int sIndex = inCornerIndex;
+               if (inTerrainTrack.getPoint(sIndex).hasAltitude()) {prevIndexWithAlt = 0;}
+               for (int i=1; i<_gridSize; i++)
+               {
+                       sIndex += inInc;
+                       if (inTerrainTrack.getPoint(sIndex).hasAltitude())
+                       {
+                               if (prevIndexWithAlt >= 0 && prevIndexWithAlt < (i-1))
+                               {
+                                       final int gapLen = i - prevIndexWithAlt;
+                                       final double alt1 = inTerrainTrack.getPoint(prevIndexWithAlt).getAltitude().getMetricValue();
+                                       final double alt2 = inTerrainTrack.getPoint(i).getAltitude().getMetricValue();
+                                       for (int j = 1; j < gapLen; j++)
+                                       {
+                                               // System.out.println("Fill in " + (prevIndexWithAlt + j) + " using " + prevIndexWithAlt + " and " + i);
+                                               final double alt = alt1 + (alt2-alt1) * j / gapLen;
+                                               final DataPoint p = inTerrainTrack.getPoint(inCornerIndex + (prevIndexWithAlt + j) * inInc);
+                                               p.setFieldValue(Field.ALTITUDE, "" + (int) alt, false);
+                                       }
+                               }
+                               prevIndexWithAlt = i;
+                       }
+               }
+       }
+
        /**
         * Try to fix bigger holes by interpolating between neighbours
         * @param inTerrainTrack terrain track
        /**
         * Try to fix bigger holes by interpolating between neighbours
         * @param inTerrainTrack terrain track
index b7c73d29cf5a6c2fd85d9627531912ea18029025..f4b3ed34d4b195f1c7a02a0d3b0476825e27b3a1 100644 (file)
@@ -1,5 +1,6 @@
 package tim.prune.threedee;
 
 package tim.prune.threedee;
 
+import tim.prune.DataStatus;
 import tim.prune.data.Track;
 
 /**
 import tim.prune.data.Track;
 
 /**
@@ -29,6 +30,11 @@ public interface ThreeDWindow
         */
        public void setTerrainParameters(TerrainDefinition inDefinition);
 
         */
        public void setTerrainParameters(TerrainDefinition inDefinition);
 
+       /**
+        * @param inStatus current data status for caching
+        */
+       public void setDataStatus(DataStatus inStatus);
+
        /**
         * Show the window
         * @throws ThreeDException when 3d classes not found
        /**
         * Show the window
         * @throws ThreeDException when 3d classes not found
diff --git a/tim/prune/undo/UndoStack.java b/tim/prune/undo/UndoStack.java
new file mode 100644 (file)
index 0000000..bca92b1
--- /dev/null
@@ -0,0 +1,24 @@
+package tim.prune.undo;
+
+import java.util.Stack;
+
+/**
+ * Stack of undo operations
+ * which also remembers how many times it's been cleared
+ */
+public class UndoStack extends Stack<UndoOperation>
+{
+       private int _numTimesDeleted = 0;
+
+       /** @return number of times this stack has been deleted */
+       public int getNumTimesDeleted() {
+               return _numTimesDeleted;
+       }
+
+       @Override
+       public void clear()
+       {
+               _numTimesDeleted++;
+               super.clear();
+       }
+}