mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 16:47:31 -05:00
#1849 Map enhancements. Adds track list, zoom to selection, history trail size and other features. (#1920)
Co-authored-by: Dennis Sheirer <dsheirer@github.com>
This commit is contained in:
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2024 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2019 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -31,6 +28,20 @@
|
||||
|
||||
package org.jdesktop.swingx;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.beans.DesignMode;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Set;
|
||||
import jiconfont.icons.font_awesome.FontAwesome;
|
||||
import jiconfont.swing.IconFontSwing;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
@@ -46,20 +57,6 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.beans.DesignMode;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A tile oriented map component that can easily be used with tile sources
|
||||
@@ -87,8 +84,7 @@ public class JXMapViewer extends JPanel implements DesignMode
|
||||
{
|
||||
private static final long serialVersionUID = -3530746298586937321L;
|
||||
|
||||
private final static Logger mLog =
|
||||
LoggerFactory.getLogger( JXMapViewer.class );
|
||||
private final static Logger mLog = LoggerFactory.getLogger(JXMapViewer.class);
|
||||
|
||||
private final boolean isNegativeYAllowed = true; // maybe rename to isNorthBounded and isSouthBounded?
|
||||
|
||||
@@ -96,25 +92,25 @@ public class JXMapViewer extends JPanel implements DesignMode
|
||||
* The zoom level. Generally a value between 1 and 15 (TODO Is this true for all the mapping worlds? What does this
|
||||
* mean if some mapping system doesn't support the zoom level?
|
||||
*/
|
||||
private int zoomLevel = 1;
|
||||
private int mZoomLevel = 1;
|
||||
|
||||
/**
|
||||
* The position, in <I>map coordinates</I> of the center point. This is defined as the distance from the top and
|
||||
* left edges of the map in pixels. Dragging the map component will change the center position. Zooming in/out will
|
||||
* cause the center to be recalculated so as to remain in the center of the new "map".
|
||||
*/
|
||||
private Point2D center = new Point2D.Double(0, 0);
|
||||
private Point2D mCenter = new Point2D.Double(0, 0);
|
||||
|
||||
/**
|
||||
* Indicates whether or not to draw the borders between tiles. Defaults to false. TODO Generally not very nice
|
||||
* looking, very much a product of testing Consider whether this should really be a property or not.
|
||||
*/
|
||||
private boolean drawTileBorders = false;
|
||||
private boolean mDrawTileBorders = false;
|
||||
|
||||
/**
|
||||
* Factory used by this component to grab the tiles necessary for painting the map.
|
||||
*/
|
||||
private TileFactory factory;
|
||||
private TileFactory mTileFactory;
|
||||
|
||||
/**
|
||||
* The position in latitude/longitude of the "address" being mapped. This is a special coordinate that, when moved,
|
||||
@@ -122,27 +118,27 @@ public class JXMapViewer extends JPanel implements DesignMode
|
||||
* (in pixels) of the viewport whereas this will not change when panning or zooming. Whenever the addressLocation is
|
||||
* changed, however, the map will be repositioned.
|
||||
*/
|
||||
private GeoPosition addressLocation;
|
||||
private GeoPosition mAddressLocation;
|
||||
|
||||
/**
|
||||
* The overlay to delegate to for painting the "foreground" of the map component. This would include painting
|
||||
* waypoints, day/night, etc. Also receives mouse events.
|
||||
*/
|
||||
private Painter<? super JXMapViewer> overlay;
|
||||
private Painter<? super JXMapViewer> mOverlay;
|
||||
|
||||
private boolean designTime;
|
||||
private boolean mDesignTime;
|
||||
|
||||
private Image loadingImage;
|
||||
private Image mLoadingImage;
|
||||
|
||||
private boolean restrictOutsidePanning = true;
|
||||
private boolean horizontalWrapped = true;
|
||||
private boolean mRestrictOutsidePanning = true;
|
||||
private boolean mHorizontalWrapped = true;
|
||||
|
||||
/**
|
||||
* Create a new JXMapViewer. By default it will use the EmptyTileFactory
|
||||
*/
|
||||
public JXMapViewer()
|
||||
{
|
||||
factory = new EmptyTileFactory();
|
||||
mTileFactory = new EmptyTileFactory();
|
||||
// setTileFactory(new GoogleTileFactory());
|
||||
|
||||
// make a dummy loading image
|
||||
@@ -153,9 +149,7 @@ public class JXMapViewer extends JPanel implements DesignMode
|
||||
}
|
||||
catch (Throwable ex)
|
||||
{
|
||||
|
||||
mLog.error( "JXMapViewer could not load default 'loading.png'" );
|
||||
|
||||
BufferedImage img = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g2 = img.createGraphics();
|
||||
g2.setColor(Color.black);
|
||||
@@ -203,7 +197,7 @@ public class JXMapViewer extends JPanel implements DesignMode
|
||||
@Override
|
||||
public void setDesignTime(boolean b)
|
||||
{
|
||||
this.designTime = b;
|
||||
this.mDesignTime = b;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -213,7 +207,7 @@ public class JXMapViewer extends JPanel implements DesignMode
|
||||
@Override
|
||||
public boolean isDesignTime()
|
||||
{
|
||||
return designTime;
|
||||
return mDesignTime;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -313,9 +307,9 @@ public class JXMapViewer extends JPanel implements DesignMode
|
||||
@SuppressWarnings("unused")
|
||||
private void drawOverlays(final int zoom, final Graphics g, final Rectangle viewportBounds)
|
||||
{
|
||||
if (overlay != null)
|
||||
if (mOverlay != null)
|
||||
{
|
||||
overlay.paint((Graphics2D) g, this, getWidth(), getHeight());
|
||||
mOverlay.paint((Graphics2D) g, this, getWidth(), getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,7 +327,7 @@ public class JXMapViewer extends JPanel implements DesignMode
|
||||
public void setOverlayPainter(Painter<? super JXMapViewer> overlay)
|
||||
{
|
||||
Painter<? super JXMapViewer> old = getOverlayPainter();
|
||||
this.overlay = overlay;
|
||||
this.mOverlay = overlay;
|
||||
|
||||
PropertyChangeListener listener = new PropertyChangeListener()
|
||||
{
|
||||
@@ -369,7 +363,7 @@ public class JXMapViewer extends JPanel implements DesignMode
|
||||
*/
|
||||
public Painter<? super JXMapViewer> getOverlayPainter()
|
||||
{
|
||||
return overlay;
|
||||
return mOverlay;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -399,7 +393,7 @@ public class JXMapViewer extends JPanel implements DesignMode
|
||||
*/
|
||||
public void setZoom(int zoom)
|
||||
{
|
||||
if (zoom == this.zoomLevel)
|
||||
if (zoom == this.mZoomLevel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -412,10 +406,10 @@ public class JXMapViewer extends JPanel implements DesignMode
|
||||
}
|
||||
|
||||
// if(zoom >= 0 && zoom <= 15 && zoom != this.zoom) {
|
||||
int oldzoom = this.zoomLevel;
|
||||
int oldzoom = this.mZoomLevel;
|
||||
Point2D oldCenter = getCenter();
|
||||
Dimension oldMapSize = getTileFactory().getMapSize(oldzoom);
|
||||
this.zoomLevel = zoom;
|
||||
this.mZoomLevel = zoom;
|
||||
this.firePropertyChange("zoom", oldzoom, zoom);
|
||||
|
||||
Dimension mapSize = getTileFactory().getMapSize(zoom);
|
||||
@@ -432,7 +426,7 @@ public class JXMapViewer extends JPanel implements DesignMode
|
||||
*/
|
||||
public int getZoom()
|
||||
{
|
||||
return this.zoomLevel;
|
||||
return this.mZoomLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -442,7 +436,7 @@ public class JXMapViewer extends JPanel implements DesignMode
|
||||
*/
|
||||
public GeoPosition getAddressLocation()
|
||||
{
|
||||
return addressLocation;
|
||||
return mAddressLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -452,7 +446,7 @@ public class JXMapViewer extends JPanel implements DesignMode
|
||||
public void setAddressLocation(GeoPosition addressLocation)
|
||||
{
|
||||
GeoPosition old = getAddressLocation();
|
||||
this.addressLocation = addressLocation;
|
||||
this.mAddressLocation = addressLocation;
|
||||
setCenter(getTileFactory().geoToPixel(addressLocation, getZoom()));
|
||||
|
||||
firePropertyChange("addressLocation", old, getAddressLocation());
|
||||
@@ -475,7 +469,7 @@ public class JXMapViewer extends JPanel implements DesignMode
|
||||
*/
|
||||
public boolean isDrawTileBorders()
|
||||
{
|
||||
return drawTileBorders;
|
||||
return mDrawTileBorders;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -485,7 +479,7 @@ public class JXMapViewer extends JPanel implements DesignMode
|
||||
public void setDrawTileBorders(boolean drawTileBorders)
|
||||
{
|
||||
boolean old = isDrawTileBorders();
|
||||
this.drawTileBorders = drawTileBorders;
|
||||
this.mDrawTileBorders = drawTileBorders;
|
||||
firePropertyChange("drawTileBorders", old, isDrawTileBorders());
|
||||
repaint();
|
||||
}
|
||||
@@ -497,7 +491,7 @@ public class JXMapViewer extends JPanel implements DesignMode
|
||||
public void setCenterPosition(GeoPosition geoPosition)
|
||||
{
|
||||
GeoPosition oldVal = getCenterPosition();
|
||||
setCenter(getTileFactory().geoToPixel(geoPosition, zoomLevel));
|
||||
setCenter(getTileFactory().geoToPixel(geoPosition, mZoomLevel));
|
||||
repaint();
|
||||
GeoPosition newVal = getCenterPosition();
|
||||
firePropertyChange("centerPosition", oldVal, newVal);
|
||||
@@ -509,7 +503,7 @@ public class JXMapViewer extends JPanel implements DesignMode
|
||||
*/
|
||||
public GeoPosition getCenterPosition()
|
||||
{
|
||||
return getTileFactory().pixelToGeo(getCenter(), zoomLevel);
|
||||
return getTileFactory().pixelToGeo(getCenter(), mZoomLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -518,7 +512,7 @@ public class JXMapViewer extends JPanel implements DesignMode
|
||||
*/
|
||||
public TileFactory getTileFactory()
|
||||
{
|
||||
return factory;
|
||||
return mTileFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -530,10 +524,10 @@ public class JXMapViewer extends JPanel implements DesignMode
|
||||
if (factory == null)
|
||||
throw new NullPointerException("factory must not be null");
|
||||
|
||||
this.factory.removeTileListener(tileLoadListener);
|
||||
this.factory.dispose();
|
||||
this.mTileFactory.removeTileListener(tileLoadListener);
|
||||
this.mTileFactory.dispose();
|
||||
|
||||
this.factory = factory;
|
||||
this.mTileFactory = factory;
|
||||
this.setZoom(factory.getInfo().getDefaultZoomLevel());
|
||||
|
||||
factory.addTileListener(tileLoadListener);
|
||||
@@ -547,7 +541,7 @@ public class JXMapViewer extends JPanel implements DesignMode
|
||||
*/
|
||||
public Image getLoadingImage()
|
||||
{
|
||||
return loadingImage;
|
||||
return mLoadingImage;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -556,7 +550,7 @@ public class JXMapViewer extends JPanel implements DesignMode
|
||||
*/
|
||||
public void setLoadingImage(Image loadingImage)
|
||||
{
|
||||
this.loadingImage = loadingImage;
|
||||
this.mLoadingImage = loadingImage;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -565,7 +559,7 @@ public class JXMapViewer extends JPanel implements DesignMode
|
||||
*/
|
||||
public Point2D getCenter()
|
||||
{
|
||||
return center;
|
||||
return mCenter;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -641,8 +635,8 @@ public class JXMapViewer extends JPanel implements DesignMode
|
||||
}
|
||||
|
||||
GeoPosition oldGP = this.getCenterPosition();
|
||||
this.center = new Point2D.Double(centerX, centerY);
|
||||
firePropertyChange("center", old, this.center);
|
||||
this.mCenter = new Point2D.Double(centerX, centerY);
|
||||
firePropertyChange("center", old, this.mCenter);
|
||||
firePropertyChange("centerPosition", oldGP, this.getCenterPosition());
|
||||
repaint();
|
||||
}
|
||||
@@ -739,7 +733,7 @@ public class JXMapViewer extends JPanel implements DesignMode
|
||||
*/
|
||||
public boolean isRestrictOutsidePanning()
|
||||
{
|
||||
return restrictOutsidePanning;
|
||||
return mRestrictOutsidePanning;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -747,7 +741,7 @@ public class JXMapViewer extends JPanel implements DesignMode
|
||||
*/
|
||||
public void setRestrictOutsidePanning(boolean restrictOutsidePanning)
|
||||
{
|
||||
this.restrictOutsidePanning = restrictOutsidePanning;
|
||||
this.mRestrictOutsidePanning = restrictOutsidePanning;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -755,7 +749,7 @@ public class JXMapViewer extends JPanel implements DesignMode
|
||||
*/
|
||||
public boolean isHorizontalWrapped()
|
||||
{
|
||||
return horizontalWrapped;
|
||||
return mHorizontalWrapped;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -763,7 +757,7 @@ public class JXMapViewer extends JPanel implements DesignMode
|
||||
*/
|
||||
public void setHorizontalWrapped(boolean horizontalWrapped)
|
||||
{
|
||||
this.horizontalWrapped = horizontalWrapped;
|
||||
this.mHorizontalWrapped = horizontalWrapped;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
******************************************************************************/
|
||||
package org.jdesktop.swingx.input;
|
||||
|
||||
import io.github.dsheirer.map.MapPanel;
|
||||
import org.jdesktop.swingx.JXMapViewer;
|
||||
|
||||
import java.awt.*;
|
||||
@@ -31,32 +32,34 @@ import java.awt.geom.Point2D;
|
||||
*/
|
||||
public class ZoomMouseWheelListenerCursor implements MouseWheelListener
|
||||
{
|
||||
private JXMapViewer viewer;
|
||||
|
||||
private MapPanel mMapPanel;
|
||||
private JXMapViewer mViewer;
|
||||
|
||||
/**
|
||||
* @param viewer the jxmapviewer
|
||||
*/
|
||||
public ZoomMouseWheelListenerCursor(JXMapViewer viewer)
|
||||
public ZoomMouseWheelListenerCursor(MapPanel mapPanel)
|
||||
{
|
||||
this.viewer = viewer;
|
||||
mMapPanel = mapPanel;
|
||||
mViewer = mMapPanel.getMapViewer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseWheelMoved(MouseWheelEvent evt)
|
||||
{
|
||||
Point current = evt.getPoint();
|
||||
Rectangle bound = viewer.getViewportBounds();
|
||||
Rectangle bound = mViewer.getViewportBounds();
|
||||
|
||||
double dx = current.x - bound.width / 2;
|
||||
double dy = current.y - bound.height / 2;
|
||||
|
||||
Dimension oldMapSize = viewer.getTileFactory().getMapSize(viewer.getZoom());
|
||||
Dimension oldMapSize = mViewer.getTileFactory().getMapSize(mViewer.getZoom());
|
||||
|
||||
viewer.setZoom(viewer.getZoom() + evt.getWheelRotation());
|
||||
|
||||
Dimension mapSize = viewer.getTileFactory().getMapSize(viewer.getZoom());
|
||||
mMapPanel.adjustZoom(evt.getWheelRotation());
|
||||
|
||||
Point2D center = viewer.getCenter();
|
||||
Dimension mapSize = mViewer.getTileFactory().getMapSize(mViewer.getZoom());
|
||||
|
||||
Point2D center = mViewer.getCenter();
|
||||
|
||||
double dzw = (mapSize.getWidth() / oldMapSize.getWidth());
|
||||
double dzh = (mapSize.getHeight() / oldMapSize.getHeight());
|
||||
@@ -64,6 +67,6 @@ public class ZoomMouseWheelListenerCursor implements MouseWheelListener
|
||||
double x = center.getX() + dx * (dzw - 1);
|
||||
double y = center.getY() + dy * (dzh - 1);
|
||||
|
||||
viewer.setCenter(new Point2D.Double(x, y));
|
||||
mViewer.setCenter(new Point2D.Double(x, y));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2024 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* GeoPosition.java
|
||||
*
|
||||
@@ -33,7 +52,6 @@ public class GeoPosition
|
||||
this.latitude = latitude;
|
||||
this.longitude = longitude;
|
||||
}
|
||||
// must be an array of length two containing lat then long in that order.
|
||||
|
||||
/**
|
||||
* Creates a new instance of GeoPosition from the specified
|
||||
@@ -89,6 +107,36 @@ public class GeoPosition
|
||||
return longitude;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the position as Degrees Minutes Seconds (DMS)
|
||||
*/
|
||||
public String toDMS()
|
||||
{
|
||||
int latDegrees = (int)Math.floor(Math.abs(latitude));
|
||||
double latMinutes = (Math.abs(latitude) - latDegrees) * 60.0;
|
||||
int latMinutesInt = (int)Math.floor(latMinutes);
|
||||
double latSeconds = (latMinutes - latMinutesInt) * 60.0;
|
||||
int latSecondsInt = (int)latSeconds;
|
||||
|
||||
int lonDegrees = (int)Math.floor(Math.abs(longitude));
|
||||
double lonMinutes = (Math.abs(longitude) - lonDegrees) * 60.0;
|
||||
int lonMinutesInt = (int)Math.floor(lonMinutes);
|
||||
double lonSeconds = (lonMinutes - lonMinutesInt) * 60.0;
|
||||
int lonSecondsInt = (int)lonSeconds;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(latDegrees).append("°");
|
||||
sb.append(latMinutesInt).append("'");
|
||||
sb.append(latSecondsInt).append("");
|
||||
sb.append(latitude >= 0 ? "N" : "S");
|
||||
sb.append(", ");
|
||||
sb.append(lonDegrees).append("°");
|
||||
sb.append(lonMinutesInt).append("'");
|
||||
sb.append(lonSecondsInt).append("");
|
||||
sb.append(longitude >= 0 ? "E" : "W");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user