Javaでグーグルマップ
GoogleMapのSWTウィジットで『Google Maps Widgets』というのをみつけた。
ちょっとおもしろいと思ったので、勉強がてら、SWTのBrowserウィジットにGoogleMapを表示して、指定範囲の緯度・経度とその画像を取得するプログラムを書いてみる。
■準備
①GoogleMapの登録をする。
②SWTを準備する。
■ソースコード
とりあえず、次のようなコードを書いてみた。
あと、JavaScriptのオブジェクトを直接に操作できなさそう?だったので、GoogleMapで取得した緯度・経度はステータスバーに書き込み、StatusTextListenerで文字列として取得している。
package test; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.DirectColorModel; import java.awt.image.IndexColorModel; import java.awt.image.WritableRaster; import java.io.File; import java.io.IOException; import java.util.Timer; import java.util.TimerTask; import javax.imageio.ImageIO; import org.eclipse.swt.SWT; import org.eclipse.swt.browser.Browser; import org.eclipse.swt.browser.ProgressAdapter; import org.eclipse.swt.browser.ProgressEvent; import org.eclipse.swt.browser.StatusTextEvent; import org.eclipse.swt.browser.StatusTextListener; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseListener; import org.eclipse.swt.events.MouseMoveListener; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.graphics.PaletteData; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Shell; public class GoogleMapTest { private Display display; private final Shell shell; private Point pos=null,pos2=null; private Browser browser; private Timer timer; private String posMes; private StatusTextListener listener; private BufferedImage img; public GoogleMapTest(){ display = new Display(); shell = new Shell(display); shell.setLayout(new FillLayout()); shell.setText("GoogleMap"); browser = new Browser(shell, SWT.NONE); browser.setUrl("GoogleMapを登録したファイルのURL"); browser.setLayout(new FillLayout()); timer=new Timer(); ProgressAdapter pa=new ProgressAdapter(){ final ProgressAdapter px=this; @Override public void completed(ProgressEvent arg0) { TimerTask task=new TimerTask(){ @Override public void run() { Runnable rr=new Runnable(){ @Override public void run() { browser.execute( "if (GBrowserIsCompatible()) {" + "var map = new GMap2(document.getElementById(\"map\"));" + "map.setCenter(new GLatLng(34.6833333333333, 135.50), 7);" + "map.addControl(new GLargeMapControl());" + "map.addControl(new GMapTypeControl());" + "map.enableContinuousZoom();"+ "map.enableScrollWheelZoom()}"); timer.cancel(); browser.removeProgressListener(px); } }; shell.getDisplay().syncExec(rr); } }; timer.schedule(task, 1000); } }; browser.addProgressListener(pa); listener = new StatusTextListener() { public void changed(StatusTextEvent event) { posMes=event.text; if(posMes.isEmpty()){ browser.execute("map.clearOverlays();"); return; } browser.removeStatusTextListener(this); Runnable rr=new Runnable(){ public void run(){ MessageBox box = new MessageBox(shell,SWT.OK|SWT.CANCEL); box.setMessage("O.K.?"); int result = box.open(); if(result==SWT.OK){ MessageBox mes = new MessageBox(shell,SWT.OK); mes.setMessage(posMes); mes.open(); FileDialog saveDialog = new FileDialog(shell,SWT.SAVE); String saveFile = saveDialog.open(); File f=new File(saveFile); try{ ImageIO.write(img, "png", f); }catch(IOException e){} display.syncExec(new Runnable(){public void run(){shell.dispose();}}); }else{ display.syncExec(new Runnable(){public void run(){ browser.removeStatusTextListener(listener); }}); } } }; display.syncExec(rr); } }; browser.addMouseListener(new MouseListener(){ @Override public void mouseDoubleClick(MouseEvent arg0) {} @Override public void mouseDown(MouseEvent arg0) {} @Override public void mouseUp(MouseEvent arg0) { if(arg0.button==3){ if(pos==null){ pos=new Point(arg0.x,arg0.y); }else{ browser.addStatusTextListener(listener); int[] px=new int[4]; pos2=new Point(arg0.x,arg0.y); if(pos.x<pos2.x){ px[0]=pos.x;px[1]=pos2.x; }else{ px[1]=pos.x;px[0]=pos2.x; } if(pos.y>pos2.y){ px[2]=pos.y;px[3]=pos2.y; }else{ px[3]=pos.y;px[2]=pos2.y; } img=processImage(); browser.execute( "lang0=map.fromContainerPixelToLatLng(new GPoint("+ Integer.toString(px[0])+","+Integer.toString(px[2])+"));"+ "lang1=map.fromContainerPixelToLatLng(new GPoint("+ Integer.toString(px[1])+","+Integer.toString(px[3])+"));"+ "window.status=lang0+'_'+lang1"); pos=null; } } } }); browser.addMouseMoveListener(new MouseMoveListener(){ @Override public void mouseMove(MouseEvent arg0) { if(pos!=null){ int[] px=new int[4]; pos2=new Point(arg0.x,arg0.y); if(pos.x<pos2.x){ px[0]=pos.x;px[1]=pos2.x; }else{ px[1]=pos.x;px[0]=pos2.x; } if(pos.y<pos2.y){ px[2]=pos.y;px[3]=pos2.y; }else{ px[3]=pos.y;px[2]=pos2.y; } String[] pixel=new String[]{ "map.fromContainerPixelToLatLng(new GPoint("+ Integer.toString(px[0])+","+Integer.toString(px[2])+"))", "map.fromContainerPixelToLatLng(new GPoint("+ Integer.toString(px[1])+","+Integer.toString(px[2])+"))", "map.fromContainerPixelToLatLng(new GPoint("+ Integer.toString(px[1])+","+Integer.toString(px[3])+"))", "map.fromContainerPixelToLatLng(new GPoint("+ Integer.toString(px[0])+","+Integer.toString(px[3])+"))", "map.fromContainerPixelToLatLng(new GPoint("+ Integer.toString(px[0])+","+Integer.toString(px[2])+"))"}; browser.execute( "map.clearOverlays();var points = [];points[0]="+pixel[0]+";"+ "points[1] ="+pixel[1]+";points[2] ="+pixel[2]+";"+ "points[3] ="+pixel[3]+";points[4] ="+pixel[4]+";"+ "var polyline = new GPolyline(points);map.addOverlay(polyline);"); } } }); shell.setMaximized(true); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); } private BufferedImage processImage(){ final GC gc = new GC(browser); Rectangle rect = shell.getClientArea(); Image img = new Image(display, rect.width, rect.height); gc.copyArea(img, 0, 0); BufferedImage bimg = swt2awt(img.getImageData()); return bimg; } private BufferedImage swt2awt(ImageData data){ ColorModel colorModel = null; PaletteData palette = data.palette; if (palette.isDirect) { colorModel = new DirectColorModel(data.depth, palette.redMask, palette.greenMask, palette.blueMask); BufferedImage bufferedImage = new BufferedImage(colorModel, colorModel.createCompatibleWritableRaster(data.width, data.height), false, null); WritableRaster raster = bufferedImage.getRaster(); int[] pixelArray = new int[3]; for (int y = 0; y < data.height; y++) { for (int x = 0; x < data.width; x++) { int pixel = data.getPixel(x, y); RGB rgb = palette.getRGB(pixel); pixelArray[0] = rgb.red; pixelArray[1] = rgb.green; pixelArray[2] = rgb.blue; raster.setPixels(x, y, 1, 1, pixelArray); } } return bufferedImage; } else { RGB[] rgbs = palette.getRGBs(); byte[] red = new byte[rgbs.length]; byte[] green = new byte[rgbs.length]; byte[] blue = new byte[rgbs.length]; for (int i = 0; i < rgbs.length; i++) { RGB rgb = rgbs[i]; red[i] = (byte) rgb.red; green[i] = (byte) rgb.green; blue[i] = (byte) rgb.blue; } if (data.transparentPixel != -1) { colorModel = new IndexColorModel(data.depth, rgbs.length, red, green, blue, data.transparentPixel); } else { colorModel = new IndexColorModel(data.depth, rgbs.length, red, green, blue); } BufferedImage bufferedImage = new BufferedImage(colorModel, colorModel.createCompatibleWritableRaster(data.width, data.height), false, null); WritableRaster raster = bufferedImage.getRaster(); int[] pixelArray = new int[1]; for (int y = 0; y < data.height; y++) { for (int x = 0; x < data.width; x++) { int pixel = data.getPixel(x, y); pixelArray[0] = pixel; raster.setPixel(x, y, pixelArray); } } return bufferedImage; } } public static void main(String[] args){ GoogleMapTest gm=new GoogleMapTest(); } }