From a94e508b8332721b65e3cc16f71da22cc46109a9 Mon Sep 17 00:00:00 2001 From: activityworkshop Date: Fri, 17 Apr 2020 11:06:25 +0200 Subject: [PATCH] Start with editable map, thanks to fperrin --- src/tim/prune/config/Config.java | 2 + .../prune/function/settings/SaveConfig.java | 34 ++++++++ src/tim/prune/gui/map/MapCanvas.java | 78 +++++++++++++++---- src/tim/prune/gui/map/MapPosition.java | 13 ++++ 4 files changed, 113 insertions(+), 14 deletions(-) diff --git a/src/tim/prune/config/Config.java b/src/tim/prune/config/Config.java index 8c6eefe..a5d99b1 100644 --- a/src/tim/prune/config/Config.java +++ b/src/tim/prune/config/Config.java @@ -109,6 +109,8 @@ public abstract class Config public static final String KEY_WAYPOINT_ICON_SIZE = "prune.waypointiconsize"; /** Id of selected timezone */ public static final String KEY_TIMEZONE_ID = "prune.timezoneid"; + /** Last used latlon range */ + public static final String KEY_LATLON_RANGE = "prune.latlonrange"; /** Initialise the default properties */ diff --git a/src/tim/prune/function/settings/SaveConfig.java b/src/tim/prune/function/settings/SaveConfig.java index b737bd2..ca88174 100644 --- a/src/tim/prune/function/settings/SaveConfig.java +++ b/src/tim/prune/function/settings/SaveConfig.java @@ -11,6 +11,8 @@ import tim.prune.App; import tim.prune.GenericFunction; import tim.prune.I18nManager; import tim.prune.config.Config; +import tim.prune.data.DoubleRange; +import tim.prune.data.Track; /** * Class to provide the function to save the config settings @@ -86,6 +88,12 @@ public class SaveConfig extends GenericFunction + currBounds.width + "x" + currBounds.height; Config.setConfigString(Config.KEY_WINDOW_BOUNDS, windowBounds); + final String latlonString = createLatLonStringForConfig(); + if (latlonString != null) + { + Config.setConfigString(Config.KEY_LATLON_RANGE, latlonString); + } + FileOutputStream outStream = null; try { @@ -103,4 +111,30 @@ public class SaveConfig extends GenericFunction // Remember where it was saved to Config.setConfigFile(inSaveFile); } + + /** + * @return semicolon-separated string containing the four values, or null + */ + private String createLatLonStringForConfig() + { + Track track = _app.getTrackInfo().getTrack(); + if (track.getNumPoints() >= 2) + { + final DoubleRange latRange = track.getLatRange(); + final DoubleRange lonRange = track.getLonRange(); + if (latRange.getRange() > 0.0 && lonRange.getRange() > 0.0) + { + StringBuffer buffer = new StringBuffer(); + buffer.append(Double.toString(latRange.getMinimum())); + buffer.append(';'); + buffer.append(Double.toString(latRange.getMaximum())); + buffer.append(';'); + buffer.append(Double.toString(lonRange.getMinimum())); + buffer.append(';'); + buffer.append(Double.toString(lonRange.getMaximum())); + return buffer.toString(); + } + } + return null; + } } diff --git a/src/tim/prune/gui/map/MapCanvas.java b/src/tim/prune/gui/map/MapCanvas.java index d305d1c..3bd7549 100644 --- a/src/tim/prune/gui/map/MapCanvas.java +++ b/src/tim/prune/gui/map/MapCanvas.java @@ -85,7 +85,7 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe /** coordinates of popup menu */ private int _popupMenuX = -1, _popupMenuY = -1; /** Flag to prevent showing too often the error message about loading maps */ - private boolean _shownOsmErrorAlready = false; + private boolean _shownMapLoadErrorAlready = false; /** Current drawing mode */ private int _drawMode = MODE_DEFAULT; /** Current waypoint icon definition */ @@ -339,8 +339,16 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe */ private void zoomToFit() { - _latRange = _track.getLatRange(); - _lonRange = _track.getLonRange(); + if (_track.getNumPoints() > 0) + { + _latRange = _track.getLatRange(); + _lonRange = _track.getLonRange(); + } + if (_latRange == null || _lonRange == null + || !_latRange.hasData() || !_lonRange.hasData()) + { + setDefaultLatLonRange(); + } _xRange = new DoubleRange(MapUtils.getXFromLongitude(_lonRange.getMinimum()), MapUtils.getXFromLongitude(_lonRange.getMaximum())); _yRange = new DoubleRange(MapUtils.getYFromLatitude(_latRange.getMinimum()), @@ -349,6 +357,37 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe getWidth(), getHeight()); } + /** + * Track data is empty, so find a default area on the map to show + */ + private void setDefaultLatLonRange() + { + String storedRange = Config.getConfigString(Config.KEY_LATLON_RANGE); + // Parse it into four latlon values + try + { + String[] values = storedRange.split(";"); + if (values.length == 4) + { + final double lat1 = Double.valueOf(values[0]); + final double lat2 = Double.valueOf(values[1]); + if (lat1 >= -90.0 && lat1 <= 90.0 && lat2 >= -90.0 && lat2 <= 90.0 && lat1 != lat2) + { + _latRange = new DoubleRange(lat1, lat2); + final double lon1 = Double.valueOf(values[2]); + final double lon2 = Double.valueOf(values[3]); + if (lon1 >= -180.0 && lon1 <= 180.0 && lon2 >= -180.0 && lon2 <= 180.0 && lon1 != lon2) + { + _lonRange = new DoubleRange(lon1, lon2); + return; + } + } + } + } + catch (Exception e) {} + _latRange = new DoubleRange(45.8, 47.9); + _lonRange = new DoubleRange(5.9, 10.6); + } /** * Paint method @@ -360,7 +399,9 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe if (_mapImage != null && (_mapImage.getWidth() != getWidth() || _mapImage.getHeight() != getHeight())) { _mapImage = null; } - if (_track.getNumPoints() > 0) + final boolean showMap = Config.getConfigBoolean(Config.KEY_SHOW_MAP); + final boolean showSomething = _track.getNumPoints() > 0 || showMap; + if (showSomething) { // Check for autopan if enabled / necessary if (_autopanCheckBox.isSelected()) @@ -373,6 +414,14 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe _prevSelectedPoint = selectedPoint; } + // Recognise empty map position, if no data has been loaded + if (_mapPosition.isEmpty()) + { + // Set to some default area + zoomToFit(); + _recalculate = true; + } + // Draw the map contents if necessary if (_mapImage == null || _recalculate) { @@ -425,6 +474,9 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe inG.drawString(I18nManager.getText("display.nodata"), 50, getHeight()/2); _scaleBar.updateScale(-1, 0); } + // enable or disable panels + _topPanel.setVisible(showSomething); + _sidePanel.setVisible(showSomething); // Draw slider etc on top paintChildren(inG); } @@ -503,7 +555,7 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe } // reset error message - if (!showMap) {_shownOsmErrorAlready = false;} + if (!showMap) {_shownMapLoadErrorAlready = false;} _recalculate = false; // Only get map tiles if selected if (showMap) @@ -941,9 +993,9 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe synchronized(this) { // Show message if loading failed (but not too many times) - if (!inIsOk && !_shownOsmErrorAlready && _mapCheckBox.isSelected()) + if (!inIsOk && !_shownMapLoadErrorAlready && _mapCheckBox.isSelected()) { - _shownOsmErrorAlready = true; + _shownMapLoadErrorAlready = true; // use separate thread to show message about failing to load osm images new Thread(new Runnable() { public void run() { @@ -1074,15 +1126,17 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe */ public void mouseClicked(MouseEvent inE) { - if (_track != null && _track.getNumPoints() > 0) + final boolean showMap = Config.getConfigBoolean(Config.KEY_SHOW_MAP); + final boolean hasPoints = _track != null && _track.getNumPoints() > 0; + if (showMap || hasPoints) { // select point if it's a left-click if (!inE.isMetaDown()) { if (inE.getClickCount() == 1) { - // single click - if (_drawMode == MODE_DEFAULT) + // single left click + if (_drawMode == MODE_DEFAULT && hasPoints) { int pointIndex = _clickedPoint; if (pointIndex == INDEX_UNKNOWN) @@ -1408,10 +1462,6 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe } } repaint(); - // enable or disable components - boolean hasData = _track.getNumPoints() > 0; - _topPanel.setVisible(hasData); - _sidePanel.setVisible(hasData); // grab focus for the key presses this.requestFocus(); } diff --git a/src/tim/prune/gui/map/MapPosition.java b/src/tim/prune/gui/map/MapPosition.java index 25f05fc..a70bbf6 100644 --- a/src/tim/prune/gui/map/MapPosition.java +++ b/src/tim/prune/gui/map/MapPosition.java @@ -17,6 +17,8 @@ public class MapPosition private int _zoom = 12; /** Factor to zoom by, 2 to the power of zoom */ private int _zoomFactor = 1 << _zoom; + /** Flag to mark if this position has ever been set */ + private boolean _empty = true; /** Maximum zoom level */ private static final int MAX_ZOOM = 21; @@ -51,6 +53,7 @@ public class MapPosition setZoom(requiredZoom); _xPosition = transformToPixels((inMinX + inMaxX) / 2.0); _yPosition = transformToPixels((inMinY + inMaxY) / 2.0); + _empty = false; } /** @@ -61,6 +64,7 @@ public class MapPosition { _zoom = inZoom; _zoomFactor = 1 << _zoom; + _empty = false; } /** @@ -93,6 +97,7 @@ public class MapPosition // Set position _xPosition = (_xPosition - inWidth/2 + (inMinX + inMaxX) / 2) * multFactor; _yPosition = (_yPosition - inHeight/2 + (inMinY + inMaxY) / 2) * multFactor; + _empty = false; } /** @@ -277,4 +282,12 @@ public class MapPosition _xPosition += inDeltaX; _yPosition += inDeltaY; } + + /** + * @return true if this position has never been set + */ + public boolean isEmpty() + { + return _empty; + } } -- 2.43.0