nl.cloudfarming.client.geoviewer.jxmap.map.JXMapPanel Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of geoviewer-jxmap Show documentation
Show all versions of geoviewer-jxmap Show documentation
AgroSense geoviewer JXMap implementation. Contains a map/geoviewer TopComponent based on the JXMap classes from swingx.
The newest version!
/**
* Copyright (C) 2008-2012 AgroSense Foundation.
*
* AgroSense 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.
*
* There are special exceptions to the terms and conditions of the GPLv3 as it is applied to
* this software, see the FLOSS License Exception
* .
*
* AgroSense 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 AgroSense. If not, see .
*/
package nl.cloudfarming.client.geoviewer.jxmap.map;
import com.vividsolutions.jts.geom.Coordinate;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.geom.Point2D;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.prefs.Preferences;
import nl.cloudfarming.client.geoviewer.jxmap.map.cache.OfflineTileFactory;
import nl.cloudfarming.client.geoviewer.jxmap.render.JXMapGeoTranslator;
import nl.cloudfarming.client.util.connection.ConnectionChecker;
import org.jdesktop.swingx.JXMapViewer;
import org.jdesktop.swingx.mapviewer.GeoPosition;
import org.jdesktop.swingx.mapviewer.TileFactoryInfo;
import org.openide.util.NbPreferences;
/**
* Wrapper around the JXMapViewer with some appropriate defaults
*
* Take notice!! The zoom function is of {@link JXMapViewer} is disabled. Instead
* we implemented a custom zoom to mouse position method. Due to non overridable
* methods implemented new methods Use {@link JXMapPanel#isZoomToMousePositionEnabled()}
* to determine zoom enabled and use {@link JXMapPanel#setZoomToMousePositionEnabled(boolean)}
* to set zoom enabled/disabled
*
* @author Timon Veenstra
*/
public class JXMapPanel extends JXMapViewer {
protected static double DEFAULT_LATITUDE = 52.155174;
protected static double DEFAULT_LONGITUDE = 5.387206;
protected static int DEFAULT_ZOOM_LEVEL = 11; // Max, any higher then 11 will default to 1!
private ConnectionChecker connectionChecker;
private PropertyChangeListener connectionChangeListener;
private static final String KEY_LATITUDE = "jxmap.lat";
private static final String KEY_LONGITUDE = "jxmap.long";
private static final String KEY_ZOOM = "jxmap.zoomlevel";
private boolean zoomEnabled;
public JXMapPanel() {
setOpaque(true);
final int max = 19;
TileFactoryInfo info = new TileFactoryInfo(1, max - 8, max,
256, true, true, // tile size is 256 and x/y orientation is normal
"http://tile.openstreetmap.org",//5/15/10.png",
"x", "y", "z") {
@Override
public String getTileUrl(int x, int y, int zoom) {
int calculatedZoom = max - zoom;
return this.baseURL + "/" + calculatedZoom + "/" + x + "/" + y + ".png";
}
};
setAddressLocation(new GeoPosition(DEFAULT_LATITUDE, DEFAULT_LONGITUDE));
setZoom(DEFAULT_ZOOM_LEVEL);
setTileFactory(new OfflineTileFactory(info));
putClientProperty("print.printable", true);
//Set the zoom disabled This class will implement the zoom capability
super.setZoomEnabled(false);
//Add our own custom zoom listener
this.addMouseWheelListener(new ZoomMouseWheelListener());
zoomEnabled = true;
connectionChecker = ConnectionChecker.getInstance();
initConnectionChangeListener();
}
private void initConnectionChangeListener() {
connectionChangeListener = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (connectionChecker.isOnline()) {
refreshMap();
}
}
};
}
/**
* force JXMapView to repaint when we are online
*/
private void refreshMap() {
Graphics g = getGraphics().create();
g.setClip(0, 0, getWidth(), getHeight());
paintComponent(g);
}
@Override
public void addNotify() {
// Set saved coordinates and zoomlevel
Preferences preferences = NbPreferences.forModule(JXMapPanel.class);
Double latitude = preferences.getDouble(KEY_LATITUDE, DEFAULT_LATITUDE); //TODO preferences names to constants?
Double longitude = preferences.getDouble(KEY_LONGITUDE, DEFAULT_LONGITUDE);
int zoomLevel = preferences.getInt(KEY_ZOOM, DEFAULT_ZOOM_LEVEL);
this.setAddressLocation(new GeoPosition(latitude, longitude));
this.setZoom(zoomLevel);
connectionChecker.addPropertyChangeListener(connectionChangeListener);
super.addNotify();
// ExplorerUtils.activateActions(manager, true);
}
@Override
public void removeNotify() {
// Save coordinates and zoomlevel.
Preferences preferences = NbPreferences.forModule(JXMapPanel.class);
preferences.putDouble(KEY_LATITUDE, this.getCenterPosition().getLatitude());
preferences.putDouble(KEY_LONGITUDE, this.getCenterPosition().getLongitude());
preferences.putInt(KEY_ZOOM, this.getZoom());
connectionChecker.removePropertyChangeListener(connectionChangeListener);
// ExplorerUtils.activateActions(manager, false);
super.removeNotify();
}
/**
* Will Always return false. Use the {@link JXMapPanel#isZoomToMousePositionEnabled()
* }
*
* @return false
*/
@Deprecated
@Override
public final boolean isZoomEnabled() {
return false;
}
/**
* Will do nothing use {@link JXMapPanel#setZoomToMousePositionEnabled(boolean)}
*
* @param zoomEnabled
*/
@Deprecated
@Override
public final void setZoomEnabled(boolean zoomEnabled) {
}
/**
* Check if the zoom to mouse position is enabled
*
* @return
*/
public boolean isZoomToMousePositionEnabled() {
return zoomEnabled;
}
/**
* Set the zoom to mouse position enabled or disabled
*
* @param enabled
*/
public void setZoomToMousePositionEnabled(boolean enabled) {
zoomEnabled = enabled;
}
/**
* Zooms to mouse position
Sets the Zoom level of the map will use
* the mouse position as a fixed position.
*
* @param zoom the zoom level to set
* @param mousePosition the mouse position to use as an fixed position in
* the map
*/
public void zoomToMousePosition(int zoom, Point2D mousePosition) {
TileFactoryInfo info = getTileFactory().getInfo();
// don't repaint if we are out of the valid zoom levels
if (info != null
&& (zoom < info.getMinimumZoomLevel()
|| zoom > info.getMaximumZoomLevel())) {
return;
}
//Determine center position
JXMapGeoTranslator geoTranslator = new JXMapGeoTranslator(this);
GeoPosition geoCenter = getCenterPosition();
Point2D centerPoint = geoTranslator.geoToPixel(null, null, new Coordinate(geoCenter.getLongitude(), geoCenter.getLatitude()));
//First determine old map size
Dimension oldMapSize = getTileFactory().getMapSize(getZoom());
//Determine new map size
Dimension newMapSize = getTileFactory().getMapSize(zoom);
//Determine scale factors
double scaleFactorX = oldMapSize.getWidth() / newMapSize.getWidth();
double scaleFactorY = oldMapSize.getHeight() / newMapSize.getHeight();
//find offset
Point2D offset = findOffset(new Point2D.Double(mousePosition.getX(), mousePosition.getY()), centerPoint, scaleFactorX, scaleFactorY);
//Calculate new center based on offset
GeoPosition newCenter = geoTranslator.pixelToGeo(null, null, new Point2D.Double(mousePosition.getX() - offset.getX(), mousePosition.getY() - offset.getY()));
//apply Zoom
setZoom(zoom);
setCenterPosition(newCenter);
repaint();
}
/**
* Get the offset between the stable point and the new center point
* Offset to the right of the stable point is negative to the left is
* positive
*
* @param stablePoint the point that needs to be stable between zoom actions
* @param centerPoint the center point of the map
* @param scaleFactorX the scale factor of x. x < 1 means zoom in
* @param scaleFactorY the scale factor of y. y < 1 means zoom in
* @return
*/
Point2D findOffset(Point2D stablePoint, Point2D centerPoint, double scaleFactorX, double scaleFactorY) {
double x = (stablePoint.getX() - centerPoint.getX()) * scaleFactorX;
double y = (stablePoint.getY() - centerPoint.getY()) * scaleFactorY;
return new Point2D.Double(x, y);
}
// zooms using the mouse wheel
private class ZoomMouseWheelListener implements MouseWheelListener {
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
if (zoomEnabled) {
zoomToMousePosition(getZoom() + e.getWheelRotation(), new Point2D.Double(e.getX(), e.getY()));
}
}
}
}