2010-05-06 11:08:58 +02:00
|
|
|
package com.osmand.swing;
|
2010-04-26 17:20:50 +02:00
|
|
|
|
|
|
|
import java.awt.BorderLayout;
|
|
|
|
import java.awt.Color;
|
2010-05-16 09:22:09 +02:00
|
|
|
import java.awt.Component;
|
2010-04-26 17:20:50 +02:00
|
|
|
import java.awt.Container;
|
|
|
|
import java.awt.Graphics;
|
2010-04-30 00:47:07 +02:00
|
|
|
import java.awt.Image;
|
2010-04-26 17:20:50 +02:00
|
|
|
import java.awt.Point;
|
2010-05-09 15:06:13 +02:00
|
|
|
import java.awt.Rectangle;
|
2010-04-30 16:35:33 +02:00
|
|
|
import java.awt.event.ActionEvent;
|
|
|
|
import java.awt.event.ActionListener;
|
2010-04-26 17:20:50 +02:00
|
|
|
import java.awt.event.ComponentAdapter;
|
|
|
|
import java.awt.event.ComponentEvent;
|
|
|
|
import java.awt.event.KeyEvent;
|
|
|
|
import java.awt.event.MouseAdapter;
|
|
|
|
import java.awt.event.MouseEvent;
|
2010-05-09 15:06:13 +02:00
|
|
|
import java.awt.event.MouseWheelEvent;
|
2010-05-15 13:07:17 +02:00
|
|
|
import java.awt.event.WindowAdapter;
|
|
|
|
import java.awt.event.WindowEvent;
|
2010-04-26 17:20:50 +02:00
|
|
|
import java.awt.image.BufferedImage;
|
|
|
|
import java.io.File;
|
|
|
|
import java.io.IOException;
|
2010-04-30 00:47:07 +02:00
|
|
|
import java.text.MessageFormat;
|
2010-04-26 17:20:50 +02:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
|
|
|
|
2010-04-30 00:47:07 +02:00
|
|
|
import javax.imageio.IIOException;
|
2010-04-26 17:20:50 +02:00
|
|
|
import javax.imageio.ImageIO;
|
2010-05-16 09:22:09 +02:00
|
|
|
import javax.swing.AbstractAction;
|
|
|
|
import javax.swing.Action;
|
|
|
|
import javax.swing.BorderFactory;
|
|
|
|
import javax.swing.Box;
|
|
|
|
import javax.swing.BoxLayout;
|
2010-05-09 15:06:13 +02:00
|
|
|
import javax.swing.JButton;
|
2010-05-14 13:44:35 +02:00
|
|
|
import javax.swing.JCheckBoxMenuItem;
|
2010-04-26 17:20:50 +02:00
|
|
|
import javax.swing.JFrame;
|
2010-05-16 09:22:09 +02:00
|
|
|
import javax.swing.JLabel;
|
2010-05-14 13:44:35 +02:00
|
|
|
import javax.swing.JMenu;
|
|
|
|
import javax.swing.JMenuBar;
|
2010-04-26 17:20:50 +02:00
|
|
|
import javax.swing.JPanel;
|
|
|
|
import javax.swing.UIManager;
|
|
|
|
|
2010-04-30 00:47:07 +02:00
|
|
|
import org.apache.commons.logging.Log;
|
|
|
|
|
2010-05-06 11:08:58 +02:00
|
|
|
import com.osmand.IMapLocationListener;
|
|
|
|
import com.osmand.LogUtil;
|
2010-04-27 14:37:49 +02:00
|
|
|
import com.osmand.data.DataTileManager;
|
2010-05-14 13:44:35 +02:00
|
|
|
import com.osmand.data.preparation.MapTileDownloader;
|
|
|
|
import com.osmand.data.preparation.MapTileDownloader.DownloadRequest;
|
|
|
|
import com.osmand.data.preparation.MapTileDownloader.IMapDownloaderCallback;
|
2010-04-30 16:35:33 +02:00
|
|
|
import com.osmand.map.ITileSource;
|
|
|
|
import com.osmand.map.TileSourceManager;
|
|
|
|
import com.osmand.map.TileSourceManager.TileSourceTemplate;
|
2010-04-27 14:37:49 +02:00
|
|
|
import com.osmand.osm.LatLon;
|
2010-04-27 23:42:19 +02:00
|
|
|
import com.osmand.osm.MapUtils;
|
2010-04-26 17:20:50 +02:00
|
|
|
|
2010-04-30 16:35:33 +02:00
|
|
|
public class MapPanel extends JPanel implements IMapDownloaderCallback {
|
2010-04-26 17:20:50 +02:00
|
|
|
|
|
|
|
private static final long serialVersionUID = 1L;
|
2010-04-30 00:47:07 +02:00
|
|
|
|
2010-05-05 11:31:54 +02:00
|
|
|
protected static final Log log = LogUtil.getLog(MapPanel.class);
|
2010-05-15 13:07:17 +02:00
|
|
|
public static final int divNonLoadedImage = 16;
|
2010-04-28 17:06:07 +02:00
|
|
|
|
2010-05-14 13:44:35 +02:00
|
|
|
public static JMenu getMenuToChooseSource(final MapPanel panel){
|
2010-05-16 23:49:11 +02:00
|
|
|
final JMenu tiles = new JMenu("Source of tiles");
|
2010-05-14 13:44:35 +02:00
|
|
|
final List<TileSourceTemplate> list = TileSourceManager.getKnownSourceTemplates();
|
2010-04-30 16:35:33 +02:00
|
|
|
for(final TileSourceTemplate l : list){
|
2010-05-14 13:44:35 +02:00
|
|
|
JCheckBoxMenuItem menuItem = new JCheckBoxMenuItem(l.getName());
|
2010-04-30 16:35:33 +02:00
|
|
|
menuItem.addActionListener(new ActionListener(){
|
|
|
|
@Override
|
|
|
|
public void actionPerformed(ActionEvent e) {
|
2010-05-14 13:44:35 +02:00
|
|
|
for(int i=0; i<tiles.getItemCount(); i++){
|
|
|
|
if(list.get(i).equals(l)){
|
|
|
|
((JCheckBoxMenuItem)tiles.getItem(i)).setSelected(true);
|
|
|
|
} else {
|
|
|
|
((JCheckBoxMenuItem)tiles.getItem(i)).setSelected(false);
|
|
|
|
}
|
|
|
|
}
|
2010-04-30 16:35:33 +02:00
|
|
|
panel.setMapName(l);
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
2010-05-15 13:07:17 +02:00
|
|
|
if(l.equals(TileSourceManager.getMapnikSource())){
|
2010-05-14 13:44:35 +02:00
|
|
|
menuItem.setSelected(true);
|
2010-05-15 13:07:17 +02:00
|
|
|
panel.setMapName(l);
|
2010-05-14 13:44:35 +02:00
|
|
|
}
|
2010-04-30 16:35:33 +02:00
|
|
|
tiles.add(menuItem);
|
|
|
|
}
|
|
|
|
|
|
|
|
return tiles;
|
|
|
|
}
|
|
|
|
|
2010-04-26 17:20:50 +02:00
|
|
|
|
|
|
|
public static void main(String[] args) throws IOException {
|
2010-05-15 13:07:17 +02:00
|
|
|
JFrame frame = new JFrame("Map view");
|
2010-04-26 17:20:50 +02:00
|
|
|
try {
|
|
|
|
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
|
|
|
} catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
|
2010-05-15 13:07:17 +02:00
|
|
|
final MapPanel panel = new MapPanel(DataExtractionSettings.getSettings().getTilesDirectory());
|
|
|
|
frame.addWindowListener(new WindowAdapter(){
|
|
|
|
@Override
|
|
|
|
public void windowClosing(WindowEvent e) {
|
|
|
|
DataExtractionSettings settings = DataExtractionSettings.getSettings();
|
|
|
|
settings.saveDefaultLocation(panel.getLatitude(), panel.getLongitude());
|
|
|
|
settings.saveDefaultZoom(panel.getZoom());
|
|
|
|
System.exit(0);
|
|
|
|
}
|
|
|
|
});
|
2010-04-26 17:20:50 +02:00
|
|
|
Container content = frame.getContentPane();
|
|
|
|
content.add(panel, BorderLayout.CENTER);
|
2010-04-30 16:35:33 +02:00
|
|
|
|
2010-05-14 13:44:35 +02:00
|
|
|
JMenuBar bar = new JMenuBar();
|
2010-04-30 16:35:33 +02:00
|
|
|
bar.add(getMenuToChooseSource(panel));
|
2010-05-14 13:44:35 +02:00
|
|
|
frame.setJMenuBar(bar);
|
2010-04-26 17:20:50 +02:00
|
|
|
frame.setSize(512, 512);
|
|
|
|
frame.setVisible(true);
|
|
|
|
|
|
|
|
}
|
2010-04-27 14:37:49 +02:00
|
|
|
|
2010-04-30 16:35:33 +02:00
|
|
|
private File tilesLocation = null;
|
|
|
|
|
2010-04-27 14:37:49 +02:00
|
|
|
// name of source map
|
2010-05-15 13:07:17 +02:00
|
|
|
private ITileSource map;
|
2010-04-26 17:20:50 +02:00
|
|
|
|
2010-04-27 14:37:49 +02:00
|
|
|
|
|
|
|
// special points to draw
|
|
|
|
private DataTileManager<LatLon> points;
|
|
|
|
|
2010-04-30 16:35:33 +02:00
|
|
|
// zoom level
|
2010-05-15 13:07:17 +02:00
|
|
|
private int zoom = 1;
|
2010-04-26 17:20:50 +02:00
|
|
|
|
|
|
|
// degree measurements (-180, 180)
|
2010-04-29 01:32:03 +02:00
|
|
|
// долгота
|
2010-05-15 13:07:17 +02:00
|
|
|
private double longitude;
|
2010-04-29 01:32:03 +02:00
|
|
|
// широта
|
2010-04-26 17:20:50 +02:00
|
|
|
// degree measurements (90, -90)
|
2010-05-15 13:07:17 +02:00
|
|
|
private double latitude;
|
2010-04-26 17:20:50 +02:00
|
|
|
|
|
|
|
private List<IMapLocationListener> listeners = new ArrayList<IMapLocationListener>();
|
|
|
|
|
2010-05-09 15:06:13 +02:00
|
|
|
private MapSelectionArea selectionArea = new MapSelectionArea();
|
|
|
|
|
|
|
|
|
2010-04-27 14:37:49 +02:00
|
|
|
// cached data to draw image
|
2010-04-30 00:47:07 +02:00
|
|
|
private Image[][] images;
|
2010-04-27 14:37:49 +02:00
|
|
|
private int xStartingImage = 0;
|
|
|
|
private int yStartingImage = 0;
|
2010-04-30 00:47:07 +02:00
|
|
|
private List<Point> pointsToDraw = new ArrayList<Point>();
|
|
|
|
|
2010-04-30 16:35:33 +02:00
|
|
|
private MapTileDownloader downloader = MapTileDownloader.getInstance();
|
2010-04-30 00:47:07 +02:00
|
|
|
Map<String, Image> cache = new HashMap<String, Image>();
|
2010-05-16 09:22:09 +02:00
|
|
|
|
|
|
|
private JLabel gpsLocation;
|
|
|
|
|
|
|
|
private JButton areaButton;
|
2010-04-27 14:37:49 +02:00
|
|
|
|
|
|
|
|
2010-04-26 17:20:50 +02:00
|
|
|
|
|
|
|
public MapPanel(File fileWithTiles) {
|
2010-04-30 16:35:33 +02:00
|
|
|
tilesLocation = fileWithTiles;
|
2010-05-15 13:07:17 +02:00
|
|
|
LatLon defaultLocation = DataExtractionSettings.getSettings().getDefaultLocation();
|
|
|
|
latitude = defaultLocation.getLatitude();
|
|
|
|
longitude = defaultLocation.getLongitude();
|
|
|
|
zoom = DataExtractionSettings.getSettings().getDefaultZoom();
|
|
|
|
|
|
|
|
|
2010-05-16 09:22:09 +02:00
|
|
|
addControls();
|
|
|
|
|
2010-04-30 16:35:33 +02:00
|
|
|
downloader.setDownloaderCallback(this);
|
|
|
|
setFocusable(true);
|
|
|
|
addComponentListener(new ComponentAdapter(){
|
|
|
|
public void componentResized(ComponentEvent e) {
|
|
|
|
prepareImage();
|
|
|
|
}
|
|
|
|
});
|
2010-05-09 15:06:13 +02:00
|
|
|
setOpaque(false);
|
2010-04-30 16:35:33 +02:00
|
|
|
MapMouseAdapter mouse = new MapMouseAdapter();
|
|
|
|
addMouseListener(mouse);
|
|
|
|
addMouseMotionListener(mouse);
|
2010-05-09 15:06:13 +02:00
|
|
|
addMouseWheelListener(mouse);
|
|
|
|
|
2010-05-16 09:22:09 +02:00
|
|
|
|
2010-04-26 17:20:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public double getXTile(){
|
2010-04-27 23:42:19 +02:00
|
|
|
return MapUtils.getTileNumberX(zoom, longitude);
|
2010-04-26 17:20:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public double getYTile(){
|
2010-04-27 23:42:19 +02:00
|
|
|
return MapUtils.getTileNumberY(zoom, latitude);
|
2010-04-26 17:20:50 +02:00
|
|
|
}
|
|
|
|
|
2010-04-30 16:35:33 +02:00
|
|
|
public int getTileSize(){
|
|
|
|
return map == null ? 256 : map.getTileSize();
|
|
|
|
}
|
|
|
|
|
2010-04-26 17:20:50 +02:00
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void paintComponent(Graphics g) {
|
|
|
|
if (images != null) {
|
|
|
|
for (int i = 0; i < images.length; i++) {
|
|
|
|
for (int j = 0; j < images[i].length; j++) {
|
2010-04-30 16:35:33 +02:00
|
|
|
if (images[i][j] == null) {
|
2010-05-15 13:07:17 +02:00
|
|
|
int div = divNonLoadedImage;
|
2010-04-30 16:35:33 +02:00
|
|
|
int tileDiv = getTileSize() / div;
|
|
|
|
for (int k1 = 0; k1 < div; k1++) {
|
|
|
|
for (int k2 = 0; k2 < div; k2++) {
|
|
|
|
if ((k1 + k2) % 2 == 0) {
|
2010-04-27 22:37:40 +02:00
|
|
|
g.setColor(Color.gray);
|
|
|
|
} else {
|
|
|
|
g.setColor(Color.white);
|
|
|
|
}
|
2010-04-30 16:35:33 +02:00
|
|
|
g.fillRect(i * getTileSize() + xStartingImage + k1 * tileDiv, j * getTileSize() + yStartingImage + k2
|
|
|
|
* tileDiv, tileDiv, tileDiv);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2010-04-26 17:20:50 +02:00
|
|
|
} else {
|
2010-04-30 16:35:33 +02:00
|
|
|
g.drawImage(images[i][j], i * getTileSize() + xStartingImage, j * getTileSize() + yStartingImage, this);
|
2010-04-26 17:20:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
g.setColor(Color.black);
|
2010-04-27 14:37:49 +02:00
|
|
|
// draw user points
|
2010-04-30 16:35:33 +02:00
|
|
|
for (Point p : pointsToDraw) {
|
2010-04-27 14:37:49 +02:00
|
|
|
g.drawOval(p.x, p.y, 3, 3);
|
|
|
|
g.fillOval(p.x, p.y, 3, 3);
|
|
|
|
}
|
2010-05-09 15:06:13 +02:00
|
|
|
|
|
|
|
if(selectionArea.isVisible()){
|
|
|
|
g.setColor(new Color(0, 0, 230, 50));
|
|
|
|
Rectangle r = selectionArea.getSelectedArea();
|
|
|
|
g.fillRect(r.x, r.y, r.width, r.height);
|
|
|
|
}
|
|
|
|
|
2010-05-16 09:22:09 +02:00
|
|
|
|
2010-05-09 15:06:13 +02:00
|
|
|
g.setColor(Color.black);
|
2010-04-30 16:35:33 +02:00
|
|
|
g.fillOval(getWidth() / 2 - 2, getHeight() / 2 - 2, 4, 4);
|
|
|
|
g.drawOval(getWidth() / 2 - 2, getHeight() / 2 - 2, 4, 4);
|
|
|
|
g.drawOval(getWidth() / 2 - 5, getHeight() / 2 - 5, 10, 10);
|
2010-05-09 15:06:13 +02:00
|
|
|
|
|
|
|
super.paintComponent(g);
|
2010-04-26 17:20:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-05-02 01:35:00 +02:00
|
|
|
|
|
|
|
|
|
|
|
public File getTilesLocation() {
|
|
|
|
return tilesLocation;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setTilesLocation(File tilesLocation) {
|
|
|
|
this.tilesLocation = tilesLocation;
|
2010-05-15 13:07:17 +02:00
|
|
|
cache.clear();
|
2010-05-02 01:35:00 +02:00
|
|
|
prepareImage();
|
|
|
|
}
|
|
|
|
|
2010-04-30 00:47:07 +02:00
|
|
|
|
2010-05-02 01:35:00 +02:00
|
|
|
public String getFileForImage (int x, int y, int zoom, String ext){
|
|
|
|
return map.getName() +"/"+zoom+"/"+(x) +"/"+y+ext+".tile";
|
2010-04-30 16:35:33 +02:00
|
|
|
}
|
|
|
|
|
2010-05-02 01:35:00 +02:00
|
|
|
public Image getImageFor(int x, int y, int zoom, boolean loadIfNeeded) throws IOException{
|
2010-04-30 16:35:33 +02:00
|
|
|
if(map == null){
|
|
|
|
return null;
|
|
|
|
}
|
2010-05-02 01:35:00 +02:00
|
|
|
String file = getFileForImage(x, y, zoom, map.getTileFormat());
|
|
|
|
if(cache.get(file) == null){
|
2010-04-30 16:35:33 +02:00
|
|
|
File en = new File(tilesLocation, file);
|
2010-04-26 17:20:50 +02:00
|
|
|
if(cache.size() > 1000){
|
|
|
|
ArrayList<String> list = new ArrayList<String>(cache.keySet());
|
|
|
|
for(int i=0; i<list.size(); i+=2){
|
|
|
|
cache.remove(list.get(i));
|
|
|
|
}
|
|
|
|
}
|
2010-05-02 01:35:00 +02:00
|
|
|
if (!downloader.isFileCurrentlyDownloaded(en)) {
|
|
|
|
if (en.exists()) {
|
|
|
|
long time = System.currentTimeMillis();
|
|
|
|
try {
|
|
|
|
cache.put(file, ImageIO.read(en));
|
|
|
|
if (log.isDebugEnabled()) {
|
2010-05-13 20:02:30 +02:00
|
|
|
log.debug("Loaded file : " + file + " " + (System.currentTimeMillis() - time) + " ms");
|
2010-05-02 01:35:00 +02:00
|
|
|
}
|
|
|
|
} catch (IIOException e) {
|
|
|
|
log.error("Eror reading png " + x + " " + y + " zoom : " + zoom, e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(loadIfNeeded && cache.get(file) == null){
|
|
|
|
String urlToLoad = map.getUrlToLoad(x, y, zoom);
|
|
|
|
if (urlToLoad != null) {
|
2010-05-06 00:29:58 +02:00
|
|
|
downloader.requestToDownload(new DownloadRequest(urlToLoad, en, x, y, zoom));
|
2010-04-30 00:47:07 +02:00
|
|
|
}
|
|
|
|
}
|
2010-05-02 01:35:00 +02:00
|
|
|
}
|
2010-04-30 00:47:07 +02:00
|
|
|
}
|
|
|
|
|
2010-04-30 16:35:33 +02:00
|
|
|
return cache.get(file);
|
2010-04-30 00:47:07 +02:00
|
|
|
}
|
|
|
|
|
2010-05-16 09:22:09 +02:00
|
|
|
public void setAreaActionHandler(Action a){
|
|
|
|
areaButton.setAction(a);
|
|
|
|
}
|
|
|
|
|
2010-04-30 16:35:33 +02:00
|
|
|
@Override
|
2010-05-06 00:29:58 +02:00
|
|
|
public void tileDownloaded(DownloadRequest request) {
|
2010-05-17 14:03:16 +02:00
|
|
|
if(request == null){
|
|
|
|
prepareImage(false);
|
|
|
|
return;
|
|
|
|
}
|
2010-04-30 21:35:25 +02:00
|
|
|
int tileSize = getTileSize();
|
|
|
|
double xTileLeft = getXTile() - getSize().width / (2d * tileSize);
|
|
|
|
double yTileUp = getYTile() - getSize().height / (2d * tileSize);
|
|
|
|
int i = request.xTile - (int)xTileLeft;
|
|
|
|
int j = request.yTile - (int)yTileUp;
|
2010-05-17 14:03:16 +02:00
|
|
|
if (request.zoom == this.zoom && (i >= 0 && i < images.length) && (j >= 0 && j < images[i].length)) {
|
2010-04-30 21:35:25 +02:00
|
|
|
try {
|
2010-05-17 14:03:16 +02:00
|
|
|
System.out.println();
|
2010-05-02 01:35:00 +02:00
|
|
|
images[i][j] = getImageFor(request.xTile, request.yTile, zoom, false);
|
2010-04-30 21:35:25 +02:00
|
|
|
repaint();
|
|
|
|
} catch (IOException e) {
|
2010-05-17 14:03:16 +02:00
|
|
|
log.error("Eror reading png " + request.xTile + " " + request.yTile + " zoom : " + zoom, e);
|
2010-04-30 21:35:25 +02:00
|
|
|
}
|
2010-05-17 14:03:16 +02:00
|
|
|
|
2010-04-30 21:35:25 +02:00
|
|
|
}
|
2010-04-30 16:35:33 +02:00
|
|
|
}
|
2010-04-30 00:47:07 +02:00
|
|
|
|
2010-04-26 17:20:50 +02:00
|
|
|
public void prepareImage(){
|
2010-05-15 13:07:17 +02:00
|
|
|
prepareImage(DataExtractionSettings.getSettings().useInternetToLoadImages());
|
2010-04-30 16:35:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public void prepareImage(boolean loadNecessaryImages){
|
2010-04-26 17:20:50 +02:00
|
|
|
try {
|
2010-04-30 16:35:33 +02:00
|
|
|
int tileSize = getTileSize();
|
2010-04-26 17:20:50 +02:00
|
|
|
if (images != null) {
|
|
|
|
for (int i = 0; i < images.length; i++) {
|
|
|
|
for (int j = 0; j < images[i].length; j++) {
|
|
|
|
// dispose
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-04-30 00:47:07 +02:00
|
|
|
double xTileLeft = getXTile() - getSize().width / (2d * tileSize);
|
|
|
|
double xTileRight = getXTile() + getSize().width / (2d * tileSize);
|
|
|
|
double yTileUp = getYTile() - getSize().height / (2d * tileSize);
|
|
|
|
double yTileDown = getYTile() + getSize().height / (2d * tileSize);
|
2010-04-27 22:37:40 +02:00
|
|
|
|
2010-04-30 00:47:07 +02:00
|
|
|
xStartingImage = -(int) ((xTileLeft - Math.floor(xTileLeft)) * tileSize);
|
|
|
|
yStartingImage = -(int) ((yTileUp - Math.floor(yTileUp)) * tileSize);
|
|
|
|
|
2010-04-30 16:35:33 +02:00
|
|
|
if(loadNecessaryImages){
|
|
|
|
downloader.refuseAllPreviousRequests();
|
|
|
|
}
|
2010-04-30 00:47:07 +02:00
|
|
|
int tileXCount = ((int) xTileRight - (int) xTileLeft + 1);
|
|
|
|
int tileYCount = ((int) yTileDown - (int) yTileUp + 1);
|
2010-04-26 17:20:50 +02:00
|
|
|
images = new BufferedImage[tileXCount][tileYCount];
|
2010-04-30 00:47:07 +02:00
|
|
|
for (int i = 0; i < images.length; i++) {
|
|
|
|
for (int j = 0; j < images[i].length; j++) {
|
2010-04-30 16:35:33 +02:00
|
|
|
int x= (int) xTileLeft + i;
|
|
|
|
int y = (int) yTileUp + j;
|
2010-05-02 01:35:00 +02:00
|
|
|
images[i][j] = getImageFor(x, y, zoom, loadNecessaryImages);
|
2010-04-26 17:20:50 +02:00
|
|
|
}
|
|
|
|
}
|
2010-04-27 14:37:49 +02:00
|
|
|
|
2010-04-30 00:47:07 +02:00
|
|
|
if (points != null) {
|
2010-04-27 23:42:19 +02:00
|
|
|
double latDown = MapUtils.getLatitudeFromTile(zoom, yTileDown);
|
|
|
|
double longDown = MapUtils.getLongitudeFromTile(zoom, xTileRight);
|
|
|
|
double latUp = MapUtils.getLatitudeFromTile(zoom, yTileUp);
|
|
|
|
double longUp = MapUtils.getLongitudeFromTile(zoom, xTileLeft);
|
2010-04-27 14:37:49 +02:00
|
|
|
List<LatLon> objects = points.getObjects(latUp, longUp, latDown, longDown);
|
|
|
|
pointsToDraw.clear();
|
2010-04-30 00:47:07 +02:00
|
|
|
for (LatLon n : objects) {
|
|
|
|
int pixX = MapUtils.getPixelShiftX(zoom, n.getLongitude(), this.longitude, tileSize) + getWidth() / 2;
|
|
|
|
int pixY = MapUtils.getPixelShiftY(zoom, n.getLatitude(), this.latitude, tileSize) + getHeight() / 2;
|
|
|
|
if (pixX >= 0 && pixY >= 0) {
|
2010-04-27 14:37:49 +02:00
|
|
|
pointsToDraw.add(new Point(pixX, pixY));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-04-26 17:20:50 +02:00
|
|
|
repaint();
|
|
|
|
} catch (IOException e) {
|
2010-04-30 21:35:25 +02:00
|
|
|
log.error("Eror reading png preparing images");
|
2010-04-26 17:20:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void setZoom(int zoom){
|
2010-05-09 15:06:13 +02:00
|
|
|
if(map != null && (zoom > map.getMaximumZoomSupported() || zoom < map.getMinimumZoomSupported())){
|
|
|
|
return;
|
|
|
|
}
|
2010-04-26 17:20:50 +02:00
|
|
|
this.zoom = zoom;
|
|
|
|
prepareImage();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setLatLon(double latitude, double longitude){
|
|
|
|
this.latitude = latitude;
|
|
|
|
this.longitude = longitude;
|
|
|
|
prepareImage();
|
|
|
|
fireMapLocationListeners();
|
|
|
|
}
|
|
|
|
|
|
|
|
public double getLatitude() {
|
|
|
|
return latitude;
|
|
|
|
}
|
|
|
|
|
|
|
|
public double getLongitude() {
|
|
|
|
return longitude;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getZoom() {
|
|
|
|
return zoom;
|
|
|
|
}
|
|
|
|
|
2010-05-09 15:06:13 +02:00
|
|
|
public MapSelectionArea getSelectionArea() {
|
|
|
|
return selectionArea;
|
|
|
|
}
|
|
|
|
|
2010-04-30 16:35:33 +02:00
|
|
|
public ITileSource getMap(){
|
2010-04-26 17:20:50 +02:00
|
|
|
return map;
|
|
|
|
}
|
|
|
|
|
2010-04-30 16:35:33 +02:00
|
|
|
public void setMapName(ITileSource map){
|
2010-04-26 17:20:50 +02:00
|
|
|
this.map = map;
|
2010-05-02 01:35:00 +02:00
|
|
|
if(map.getMaximumZoomSupported() < this.zoom){
|
|
|
|
zoom = map.getMaximumZoomSupported();
|
|
|
|
}
|
|
|
|
if(map.getMinimumZoomSupported() > this.zoom){
|
|
|
|
zoom = map.getMinimumZoomSupported();
|
|
|
|
}
|
2010-04-26 17:20:50 +02:00
|
|
|
prepareImage();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void addMapLocationListener(IMapLocationListener l){
|
|
|
|
listeners.add(l);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void removeMapLocationListener(IMapLocationListener l){
|
|
|
|
listeners.remove(l);
|
|
|
|
}
|
|
|
|
|
2010-05-16 09:22:09 +02:00
|
|
|
private void updateLocationLabel(){
|
|
|
|
gpsLocation.setText(MessageFormat.format("Lat : {0}, lon : {1}, zoom : {2}", latitude, longitude, zoom));
|
|
|
|
}
|
|
|
|
|
2010-04-26 17:20:50 +02:00
|
|
|
protected void fireMapLocationListeners(){
|
2010-05-16 09:22:09 +02:00
|
|
|
updateLocationLabel();
|
2010-04-26 17:20:50 +02:00
|
|
|
for(IMapLocationListener l : listeners){
|
2010-04-29 01:32:03 +02:00
|
|
|
l.locationChanged(latitude, longitude, null);
|
2010-04-26 17:20:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void processKeyEvent(KeyEvent e) {
|
|
|
|
boolean processed = false;
|
|
|
|
if (e.getID() == KeyEvent.KEY_RELEASED) {
|
|
|
|
if (e.getKeyCode() == 37) {
|
2010-04-27 14:37:49 +02:00
|
|
|
// LEFT button
|
2010-04-27 23:42:19 +02:00
|
|
|
longitude = MapUtils.getLongitudeFromTile(zoom, getXTile()-0.5);
|
2010-04-26 17:20:50 +02:00
|
|
|
processed = true;
|
|
|
|
} else if (e.getKeyCode() == 39) {
|
2010-04-27 14:37:49 +02:00
|
|
|
// RIGHT button
|
2010-04-27 23:42:19 +02:00
|
|
|
longitude = MapUtils.getLongitudeFromTile(zoom, getXTile()+0.5);
|
2010-04-26 17:20:50 +02:00
|
|
|
processed = true;
|
|
|
|
} else if (e.getKeyCode() == 38) {
|
2010-04-27 14:37:49 +02:00
|
|
|
// UP button
|
2010-04-27 23:42:19 +02:00
|
|
|
latitude = MapUtils.getLatitudeFromTile(zoom, getYTile()-0.5);
|
2010-04-26 17:20:50 +02:00
|
|
|
processed = true;
|
|
|
|
} else if (e.getKeyCode() == 40) {
|
2010-04-27 14:37:49 +02:00
|
|
|
// DOWN button
|
2010-04-27 23:42:19 +02:00
|
|
|
latitude = MapUtils.getLatitudeFromTile(zoom, getYTile()+0.5);
|
2010-04-26 17:20:50 +02:00
|
|
|
processed = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(e.getID() == KeyEvent.KEY_TYPED){
|
2010-05-16 09:22:09 +02:00
|
|
|
if(e.getKeyChar() == '+' || e.getKeyChar() == '=' ){
|
2010-04-30 16:35:33 +02:00
|
|
|
if(zoom < map.getMaximumZoomSupported()){
|
2010-04-30 00:47:07 +02:00
|
|
|
zoom ++;
|
|
|
|
processed = true;
|
|
|
|
}
|
2010-04-26 17:20:50 +02:00
|
|
|
} else if(e.getKeyChar() == '-'){
|
2010-04-30 16:35:33 +02:00
|
|
|
if(zoom > map.getMinimumZoomSupported()){
|
2010-04-30 00:47:07 +02:00
|
|
|
zoom --;
|
|
|
|
processed = true;
|
|
|
|
}
|
2010-04-26 17:20:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(processed){
|
|
|
|
e.consume();
|
|
|
|
prepareImage();
|
|
|
|
fireMapLocationListeners();
|
|
|
|
}
|
|
|
|
super.processKeyEvent(e);
|
|
|
|
}
|
|
|
|
|
2010-04-27 14:37:49 +02:00
|
|
|
public DataTileManager<LatLon> getPoints() {
|
|
|
|
return points;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setPoints(DataTileManager<LatLon> points) {
|
|
|
|
this.points = points;
|
2010-05-09 15:06:13 +02:00
|
|
|
prepareImage();
|
|
|
|
}
|
|
|
|
|
2010-05-16 09:22:09 +02:00
|
|
|
public void addControls(){
|
|
|
|
BoxLayout layout = new BoxLayout(this, BoxLayout.LINE_AXIS);
|
|
|
|
setLayout(layout);
|
|
|
|
setBorder(BorderFactory.createEmptyBorder(2, 10, 10, 10));
|
|
|
|
|
|
|
|
gpsLocation = new JLabel();
|
|
|
|
gpsLocation.setOpaque(false);
|
|
|
|
updateLocationLabel();
|
|
|
|
|
2010-05-09 15:06:13 +02:00
|
|
|
JButton zoomIn = new JButton("+");
|
|
|
|
JButton zoomOut = new JButton("-");
|
2010-05-16 09:22:09 +02:00
|
|
|
areaButton = new JButton();
|
|
|
|
areaButton.setAction(new AbstractAction("Preload area"){
|
|
|
|
private static final long serialVersionUID = -5512220294374994021L;
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void actionPerformed(ActionEvent e) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
2010-05-09 15:06:13 +02:00
|
|
|
zoomIn.addActionListener(new ActionListener(){
|
|
|
|
@Override
|
|
|
|
public void actionPerformed(ActionEvent e) {
|
|
|
|
setZoom(getZoom() + 1);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
zoomOut.addActionListener(new ActionListener(){
|
|
|
|
@Override
|
|
|
|
public void actionPerformed(ActionEvent e) {
|
|
|
|
setZoom(getZoom() - 1);
|
|
|
|
}
|
|
|
|
});
|
2010-05-16 09:22:09 +02:00
|
|
|
|
|
|
|
add(gpsLocation);
|
|
|
|
add(Box.createHorizontalGlue());
|
|
|
|
add(areaButton);
|
2010-05-09 15:06:13 +02:00
|
|
|
add(zoomIn);
|
|
|
|
add(zoomOut);
|
2010-05-16 09:22:09 +02:00
|
|
|
gpsLocation.setAlignmentY(Component.TOP_ALIGNMENT);
|
|
|
|
areaButton.setVisible(false);
|
|
|
|
areaButton.setAlignmentY(Component.TOP_ALIGNMENT);
|
|
|
|
zoomOut.setAlignmentY(Component.TOP_ALIGNMENT);
|
|
|
|
zoomIn.setAlignmentY(Component.TOP_ALIGNMENT);
|
2010-05-09 15:06:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public class MapSelectionArea {
|
|
|
|
|
|
|
|
private double lat1;
|
|
|
|
private double lon1;
|
|
|
|
private double lat2;
|
|
|
|
private double lon2;
|
|
|
|
|
|
|
|
|
|
|
|
public double getLat1() {
|
|
|
|
return lat1;
|
|
|
|
}
|
|
|
|
|
|
|
|
public double getLat2() {
|
|
|
|
return lat2;
|
|
|
|
}
|
|
|
|
|
|
|
|
public double getLon1() {
|
|
|
|
return lon1;
|
|
|
|
}
|
|
|
|
|
|
|
|
public double getLon2() {
|
|
|
|
return lon2;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Rectangle getSelectedArea(){
|
|
|
|
Rectangle r = new Rectangle();
|
|
|
|
r.x = getWidth() / 2 + MapUtils.getPixelShiftX(zoom, lon1, getLongitude(), getTileSize());
|
|
|
|
r.y = getHeight() / 2 + MapUtils.getPixelShiftY(zoom, lat1, getLatitude(), getTileSize());
|
|
|
|
r.width = getWidth() / 2 + MapUtils.getPixelShiftX(zoom, lon2, getLongitude(), getTileSize()) - r.x;
|
|
|
|
r.height = getHeight() / 2 + MapUtils.getPixelShiftY(zoom, lat2, getLatitude(), getTileSize()) - r.y;
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isVisible(){
|
|
|
|
if(lat1 == lat2 || lon1 == lon2){
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
Rectangle area = getSelectedArea();
|
|
|
|
return area.width > 4 && area.height > 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void setSelectedArea(int x1, int y1, int x2, int y2){
|
|
|
|
int rx1 = Math.min(x1, x2);
|
|
|
|
int rx2 = Math.max(x1, x2);
|
|
|
|
int ry1 = Math.min(y1, y2);
|
|
|
|
int ry2 = Math.max(y1, y2);
|
|
|
|
int zoom = getZoom();
|
|
|
|
double xTile = getXTile();
|
|
|
|
double yTile = getYTile();
|
|
|
|
int wid = getWidth();
|
|
|
|
int h = getHeight();
|
|
|
|
int tileSize = getTileSize();
|
|
|
|
|
|
|
|
double xTile1 = xTile - (wid / 2 - rx1) / ((double)tileSize);
|
|
|
|
double yTile1 = yTile - (h / 2 - ry1) / ((double)tileSize);
|
|
|
|
double xTile2 = xTile - (wid / 2 - rx2) / ((double)tileSize);
|
|
|
|
double yTile2 = yTile - (h / 2 - ry2) / ((double)tileSize);
|
|
|
|
lat1 = MapUtils.getLatitudeFromTile(zoom, yTile1);
|
|
|
|
lat2 = MapUtils.getLatitudeFromTile(zoom, yTile2);
|
|
|
|
lon1 = MapUtils.getLongitudeFromTile(zoom, xTile1);
|
|
|
|
lon2 = MapUtils.getLongitudeFromTile(zoom, xTile2);
|
2010-05-16 09:22:09 +02:00
|
|
|
areaButton.setVisible(isVisible());
|
2010-05-09 15:06:13 +02:00
|
|
|
}
|
|
|
|
|
2010-04-27 14:37:49 +02:00
|
|
|
}
|
|
|
|
|
2010-04-26 17:20:50 +02:00
|
|
|
public class MapMouseAdapter extends MouseAdapter {
|
|
|
|
private Point startDragging = null;
|
2010-05-09 15:06:13 +02:00
|
|
|
private Point startSelecting = null;
|
2010-04-26 17:20:50 +02:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public void mouseClicked(MouseEvent e) {
|
|
|
|
if(e.getButton() == MouseEvent.BUTTON1){
|
|
|
|
requestFocus();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void dragTo(Point p){
|
2010-04-30 16:35:33 +02:00
|
|
|
double dx = (startDragging.x - (double)p.x)/getTileSize();
|
|
|
|
double dy = (startDragging.y - (double)p.y)/getTileSize();
|
2010-04-27 23:42:19 +02:00
|
|
|
double lat = MapUtils.getLatitudeFromTile(zoom, getYTile() + dy);
|
|
|
|
double lon = MapUtils.getLongitudeFromTile(zoom, getXTile() + dx);
|
2010-04-26 17:20:50 +02:00
|
|
|
setLatLon(lat, lon);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void mouseDragged(MouseEvent e) {
|
|
|
|
if(startDragging != null){
|
|
|
|
if(Math.abs(e.getPoint().x - startDragging.x) + Math.abs(e.getPoint().y - startDragging.y) >= 8){
|
|
|
|
dragTo(e.getPoint());
|
|
|
|
startDragging = e.getPoint();
|
|
|
|
}
|
|
|
|
}
|
2010-05-09 15:06:13 +02:00
|
|
|
if(startSelecting != null){
|
|
|
|
selectionArea.setSelectedArea(startSelecting.x, startSelecting.y, e.getPoint().x, e.getPoint().y);
|
|
|
|
updateUI();
|
|
|
|
}
|
2010-04-26 17:20:50 +02:00
|
|
|
}
|
|
|
|
|
2010-05-09 15:06:13 +02:00
|
|
|
@Override
|
|
|
|
public void mouseWheelMoved(MouseWheelEvent e) {
|
|
|
|
if(e.getWheelRotation() < 0){
|
|
|
|
setZoom(getZoom() + 1);
|
|
|
|
} else if(e.getWheelRotation() > 0) {
|
|
|
|
setZoom(getZoom() - 1);
|
|
|
|
}
|
|
|
|
super.mouseWheelMoved(e);
|
|
|
|
}
|
2010-04-26 17:20:50 +02:00
|
|
|
@Override
|
|
|
|
public void mousePressed(MouseEvent e) {
|
|
|
|
if(e.getButton() == MouseEvent.BUTTON3){
|
|
|
|
if(startDragging == null){
|
|
|
|
startDragging = e.getPoint();
|
|
|
|
}
|
2010-05-09 15:06:13 +02:00
|
|
|
} else if(e.getButton() == MouseEvent.BUTTON1){
|
|
|
|
startSelecting = e.getPoint();
|
2010-04-26 17:20:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
@Override
|
|
|
|
public void mouseReleased(MouseEvent e) {
|
|
|
|
if(e.getButton() == MouseEvent.BUTTON3){
|
|
|
|
if(startDragging != null){
|
|
|
|
dragTo(e.getPoint());
|
|
|
|
fireMapLocationListeners();
|
|
|
|
startDragging = null;
|
|
|
|
}
|
|
|
|
}
|
2010-05-09 15:06:13 +02:00
|
|
|
if(e.getButton() == MouseEvent.BUTTON1){
|
|
|
|
if(startSelecting != null){
|
|
|
|
selectionArea.setSelectedArea(startSelecting.x, startSelecting.y, e.getPoint().x, e.getPoint().y);
|
|
|
|
startSelecting = null;
|
|
|
|
updateUI();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2010-04-26 17:20:50 +02:00
|
|
|
super.mouseReleased(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|