OpenStreetMapで天気予報地図(2)

 2009-06-20のプログラムを少し修正してみた。
 まず、URLImageIconWaypointクラスを修正し、天気予報アイコンの背後色を透明にした。
 また、Rolloverクラス等を記述し、天気予報アイコンにマウスカーソルを重ねると、週間予報が表示されるようにしてみた。

■実行結果


ソースコード
 URLImageIconWaypoint.javaを以下のように修正し、また、Rollover.javaを作成した。
 また、WeatherChecker.javaのコンストラクタへ以下のコードを追加した。

・WeatherChecker.javaのコンストラクタに追加

	Rollover rl=new Rollover(waypoints);
	kit.getMainMap().addMouseMotionListener(rl);


・URLImageIconWaypoint.java

package test;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.imageio.ImageIO;

import org.jdesktop.swingx.mapviewer.Waypoint;

public class URLImageIconWaypoint extends Waypoint {
	private static Map<String,BufferedImage> imageMap=new HashMap<String,BufferedImage>();
	private BufferedImage[] img;

	public URLImageIconWaypoint(double latitude, double longitude,List<String> urls) 
		throws IOException{
		super(latitude, longitude);
		img=new BufferedImage[urls.size()];
		int id=0;
		for(String url : urls){
			img[id++]=urlToImage(new URL(url));
		}
	}

	private static BufferedImage urlToImage(URL url) throws IOException{
		BufferedImage ret=imageMap.get(url.toExternalForm());
		if(ret==null){
			ret=transColor(new Color(255,255,255,255),ImageIO.read(url));
			imageMap.put(url.toExternalForm(), ret);
			return ret;
		}else{
			return ret;
		}
	}
	
	public BufferedImage getImage(){
		return img[0];
	}
	
	public BufferedImage[] getImages(){
		return img;
	}
	
	public static final BufferedImage transColor(Color arg0,BufferedImage img){
		BufferedImage ret=new BufferedImage(
			img.getWidth(),img.getHeight(),BufferedImage.TYPE_INT_ARGB);
		int tmp=arg0.getRGB();
		int w=img.getWidth();
		int h=img.getHeight();
		for(int x=0;x<w;x++){
			for(int y=0;y<h;y++){
				if(img.getRGB(x,y)==tmp){
					ret.setRGB(x,y,0);
				}else{
					ret.setRGB(x,y,img.getRGB(x,y));
				}
			}
		}
		return ret;
	}
	
	public static BufferedImage getURLImage(URL url){
		return imageMap.get(url);
	}
}

・Rollover.java

package test;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.util.Set;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPopupMenu;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

import org.jdesktop.swingx.JXMapViewer;
import org.jdesktop.swingx.mapviewer.GeoPosition;
import org.jdesktop.swingx.mapviewer.Waypoint;

public class Rollover extends MouseMotionAdapter {
	private JPopupMenu pop;
	private Set<Waypoint> waypoints;
	private DefaultTableModel model;
	
	public Rollover(Set<Waypoint> w){
		waypoints=w;
		pop=new JPopupMenu();
		pop.setBackground(new Color(0x00000000, true));
		pop.setOpaque(false);
		JTable table=new JTable();
		table.setOpaque(false);
		table.setBorder(BorderFactory.createEmptyBorder());
		table.setBackground(new Color(0x00000000, true));
		table.setDefaultRenderer(Object.class, new ImageRenderer());
		table.setRowHeight(38);
		pop.add(table);
		model=new DefaultTableModel(){
			private static final long serialVersionUID = 1L;
			@Override
			public boolean isCellEditable(int arg0, int arg1) {
				return false;
			}
		};
		model.setRowCount(1);
		model.setColumnCount(7);
		table.setModel(model);
	}
	
	@Override
	public void mouseMoved(MouseEvent e) {
		JXMapViewer map=(JXMapViewer)e.getSource();
		Point p=e.getPoint();
		Rectangle rect=map.getViewportBounds();
		Point2D px=new Point2D.Float(p.x+rect.x,p.y+rect.y);
		GeoPosition gp=map.getTileFactory().pixelToGeo(px, map.getZoom());
		double min=Double.MAX_VALUE;
		Waypoint sp=null;
		for(Waypoint wp :waypoints){
			GeoPosition gx=wp.getPosition();
			double x=gp.getLatitude()-gx.getLatitude();
			double y=gp.getLongitude()-gx.getLongitude();
			double t=x*x+y*y;
			if(t<min){
				min=t;
				sp=wp;
			}
		}
		if(sp!=null&&min<0.02){
			URLImageIconWaypoint up=(URLImageIconWaypoint)sp;
			BufferedImage[] bi=up.getImages();
			for(int i=0;i<7;i++)model.setValueAt(bi[i], 0, i);
			pop.show(map, p.x+20, p.y-20);
		}else{
			pop.setVisible(false);
		}
	}
	
	private class ImageRenderer implements javax.swing.table.TableCellRenderer{
		private JLabel ll=new JLabel("");
		
		public ImageRenderer(){
			ll.setPreferredSize(new Dimension(60,35));
		}
		
		@Override
		public Component getTableCellRendererComponent(JTable table,
				Object value, boolean isSelected, boolean hasFocus, int row,
				int column) {
			if(value instanceof BufferedImage){
				ImageIcon icon=new ImageIcon((BufferedImage)value);
				ll.setIcon(icon);
				return ll;
			}else{
				return null;
			}
		}
		
	}
}