/** 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 */
*/
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()),
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
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())
_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)
{
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);
}
}
// reset error message
- if (!showMap) {_shownOsmErrorAlready = false;}
+ if (!showMap) {_shownMapLoadErrorAlready = false;}
_recalculate = false;
// Only get map tiles if selected
if (showMap)
final int[] xPixels = new int[numPoints];
final int[] yPixels = new int[numPoints];
- final int pointSeparationForArrowsSqd = 350;
+ final int pointSeparationForArrowsSqd = 400;
final int pointSeparation1dForArrows = (int) (Math.sqrt(pointSeparationForArrowsSqd) * 0.7);
+ final int hugePointSeparationForArrows = 120;
// try to set line width for painting
if (inG instanceof Graphics2D)
pointsPainted = true;
// Now consider whether we need to draw an arrow as well
- if (drawArrows
- && !drawnLastArrow
- && (Math.abs(prevX-px) > pointSeparation1dForArrows || Math.abs(prevY-py) > pointSeparation1dForArrows))
+ if (drawArrows)
{
- final double pointSeparationSqd = (prevX-px) * (prevX-px) + (prevY-py) * (prevY-py);
- if (pointSeparationSqd > pointSeparationForArrowsSqd)
+ final double pointDist = Math.max(Math.abs(prevX - px), Math.abs(prevY - py));
+ final int separationLimit = (drawnLastArrow ? hugePointSeparationForArrows : pointSeparation1dForArrows);
+ if (pointDist > separationLimit)
{
- final double midX = (prevX + px) / 2;
- final double midY = (prevY + py) / 2;
- final boolean midPointVisible = midX >= 0 && midX < winWidth && midY >= 0 && midY < winHeight;
- if (midPointVisible)
+ final double pointSeparationSqd = (prevX-px) * (prevX-px) + (prevY-py) * (prevY-py);
+ if (pointSeparationSqd > pointSeparationForArrowsSqd)
{
- final double alpha = Math.atan2(py - prevY, px - prevX);
- //System.out.println("Draw arrow from (" + prevX + "," + prevY + ") to (" + px + "," + py
- // + ") with angle" + (int) (alpha * 180/Math.PI));
- final double MID_TO_VERTEX = 3.0;
- final double arrowX = MID_TO_VERTEX * Math.cos(alpha);
- final double arrowY = MID_TO_VERTEX * Math.sin(alpha);
- final double vertexX = midX + arrowX;
- final double vertexY = midY + arrowY;
- inG.drawLine((int)(midX-arrowX-2*arrowY), (int)(midY-arrowY+2*arrowX), (int)vertexX, (int)vertexY);
- inG.drawLine((int)(midX-arrowX+2*arrowY), (int)(midY-arrowY-2*arrowX), (int)vertexX, (int)vertexY);
+ final double midX = (prevX + px) / 2.0;
+ final double midY = (prevY + py) / 2.0;
+ final boolean midPointVisible = midX >= 0 && midX < winWidth && midY >= 0 && midY < winHeight;
+ if (midPointVisible)
+ {
+ final double alpha = Math.atan2(py - prevY, px - prevX);
+ //System.out.println("Draw arrow from (" + prevX + "," + prevY + ") to (" + px + "," + py
+ // + ") with angle" + (int) (alpha * 180/Math.PI));
+ final double MID_TO_VERTEX = 3.0;
+ final double arrowX = MID_TO_VERTEX * Math.cos(alpha);
+ final double arrowY = MID_TO_VERTEX * Math.sin(alpha);
+ final double vertexX = midX + arrowX;
+ final double vertexY = midY + arrowY;
+ inG.drawLine((int)(midX-arrowX-2*arrowY), (int)(midY-arrowY+2*arrowX), (int)vertexX, (int)vertexY);
+ inG.drawLine((int)(midX-arrowX+2*arrowY), (int)(midY-arrowY-2*arrowX), (int)vertexX, (int)vertexY);
+ }
+ drawnLastArrow = midPointVisible;
}
- drawnLastArrow = midPointVisible;
}
- }
- else
- {
- drawnLastArrow = false;
+ else
+ {
+ drawnLastArrow = false;
+ }
}
}
prevX = px; prevY = py;
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() {
}
}
+ /**
+ * Inform that a cache failure occurred
+ */
+ public void reportCacheFailure()
+ {
+ // Cache can't be used, so disable it - user will be reminded to set it up by the tips
+ Config.setConfigString(Config.KEY_DISK_CACHE, null);
+ }
+
/**
* Zoom out, if not already at minimum zoom
*/
*/
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)
}
}
repaint();
- // enable or disable components
- boolean hasData = _track.getNumPoints() > 0;
- _topPanel.setVisible(hasData);
- _sidePanel.setVisible(hasData);
// grab focus for the key presses
this.requestFocus();
}