From: Anthony Towns Date: Sat, 20 Nov 2010 14:07:16 +0000 (+1000) Subject: AltosSiteMap: automatic fetching of map data X-Git-Tag: debian/0.7.1+117+ge7954c8~8^2~6 X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=commitdiff_plain;h=25ffe1cc7823895886b4777f310b4bda1c80133b AltosSiteMap: automatic fetching of map data --- diff --git a/ao-tools/altosui/AltosSiteMapLabel.java b/ao-tools/altosui/AltosSiteMapLabel.java new file mode 100644 index 00000000..1a371c5b --- /dev/null +++ b/ao-tools/altosui/AltosSiteMapLabel.java @@ -0,0 +1,142 @@ +/* + * Copyright © 2010 Anthony Towns + * + * 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; version 2 of the License. + * + * 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, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package altosui; + +import java.awt.*; +import java.awt.image.*; +import java.awt.event.*; +import javax.swing.*; +import javax.imageio.ImageIO; +import javax.swing.table.*; +import java.io.*; +import java.util.*; +import java.text.*; +import java.util.prefs.*; +import java.net.URL; +import java.net.URLConnection; + +public class AltosSiteMapLabel extends JLabel { + public static boolean fetchMap(File file, String url) { + URL u; + try { + u = new URL(url); + } catch (java.net.MalformedURLException e) { + return false; + } + + byte[] data; + try { + URLConnection uc = u.openConnection(); + int contentLength = uc.getContentLength(); + InputStream in = new BufferedInputStream(uc.getInputStream()); + int bytesRead = 0; + int offset = 0; + data = new byte[contentLength]; + while (offset < contentLength) { + bytesRead = in.read(data, offset, data.length - offset); + if (bytesRead == -1) + break; + offset += bytesRead; + } + in.close(); + + if (offset != contentLength) { + return false; + } + } catch (IOException e) { + return false; + } + + try { + FileOutputStream out = new FileOutputStream(file); + out.write(data); + out.flush(); + out.close(); + } catch (FileNotFoundException e) { + return false; + } catch (IOException e) { + if (file.exists()) { + file.delete(); + } + return false; + } + return true; + } + + public void fetchAndLoadMap(final File pngfile, final String url) { + System.out.printf("# Trying to fetch %s...\n", pngfile); + + Thread thread = new Thread() { + public void run() { + try { + if (fetchMap(pngfile, url)) { + setIcon(new ImageIcon(ImageIO.read(pngfile))); + } + } catch (Exception e) { + System.out.printf("# Failed to fetch file %s\n", pngfile); + System.out.printf(" wget -O '%s' ''\n", pngfile, url); + } + } + }; + thread.start(); + } + + public void fetchMap(double lat, double lng, int zoom, int px_size) { + File pngfile = MapFile(lat, lng, zoom); + String url = MapURL(lat, lng, zoom, px_size); + + if (!pngfile.exists()) { + fetchMap(pngfile, url); + } + } + + public void loadMap(double lat, double lng, int zoom, int px_size) { + File pngfile = MapFile(lat, lng, zoom); + String url = MapURL(lat, lng, zoom, px_size); + + if (!pngfile.exists()) { + fetchAndLoadMap(pngfile, url); + return; + } + + try { + setIcon(new ImageIcon(ImageIO.read(pngfile))); + return; + } catch (IOException e) { + System.out.printf("# IO error trying to load %s\n", pngfile); + return; + } + } + + private static File MapFile(double lat, double lng, int zoom) { + char chlat = lat < 0 ? 'S' : 'N'; + char chlng = lng < 0 ? 'E' : 'W'; + if (lat < 0) lat = -lat; + if (lng < 0) lng = -lng; + return new File(AltosPreferences.logdir(), + String.format("map-%c%.6f,%c%.6f-%d.png", + chlat, lat, chlng, lng, zoom)); + } + + private static String MapURL(double lat, double lng, + int zoom, int px_size) + { + return String.format("http://maps.google.com/maps/api/staticmap?center=%.6f,%.6f&zoom=%d&size=%dx%d&sensor=false&maptype=hybrid&format=png32", lat, lng, zoom, px_size, px_size); + } +} + diff --git a/ao-tools/altosui/AltosSiteMapTile.java b/ao-tools/altosui/AltosSiteMapTile.java index ca68412a..56bc98af 100644 --- a/ao-tools/altosui/AltosSiteMapTile.java +++ b/ao-tools/altosui/AltosSiteMapTile.java @@ -37,7 +37,7 @@ public class AltosSiteMapTile extends JLayeredPane { Point2D.Double coord_pt; Point2D.Double last_pt; - JLabel mapLabel; + AltosSiteMapLabel mapLabel; JLabel draw; Graphics2D g2d; @@ -48,15 +48,7 @@ public class AltosSiteMapTile extends JLayeredPane { private void loadMap() { Point2D.Double map_latlng = latlng(px_size/2, px_size/2); - File pngfile = new File(AltosPreferences.logdir(), - FileCoord(map_latlng, zoom)); - try { - mapLabel.setIcon(new ImageIcon(ImageIO.read(pngfile))); - } catch (Exception e) { - // throw new RuntimeException(e); - System.out.printf("# Failed to find file %s\n", pngfile); - System.out.printf(" wget -O '%s' 'http://maps.google.com/maps/api/staticmap?center=%.6f,%.6f&zoom=%d&size=%dx%d&sensor=false&maptype=hybrid&format=png32'\n", pngfile, map_latlng.x, map_latlng.y, zoom, px_size, px_size); - } + mapLabel.loadMap(map_latlng.x, map_latlng.y, zoom, px_size); } private boolean setLocation(double lat, double lng) { @@ -88,22 +80,6 @@ public class AltosSiteMapTile extends JLayeredPane { return v; } - private static String FileCoord(Point2D.Double latlng, int zoom) { - double lat, lng; - lat = latlng.x; - lng = latlng.y; - return FileCoord(lat, lng, zoom); - } - private static String FileCoord(double lat, double lng, int zoom) { - char chlat = lat < 0 ? 'S' : 'N'; - char chlng = lng < 0 ? 'E' : 'W'; - if (lat < 0) lat = -lat; - if (lng < 0) lng = -lng; - return String.format("map-%c%.6f,%c%.6f-%d.png", - chlat, lat, chlng, lng, zoom); - } - - // based on google js // http://maps.gstatic.com/intl/en_us/mapfiles/api-3/2/10/main.js // search for fromLatLngToPoint and fromPointToLatLng @@ -172,7 +148,7 @@ public class AltosSiteMapTile extends JLayeredPane { if (last_pt == null) { setLocation(state.pad_lat, state.pad_lon); loadMap(); - last_pt = pt; + last_pt = pt(state.pad_lat, state.pad_lon); } Point2D.Double pt = pt(state.gps.lat, state.gps.lon); @@ -221,7 +197,7 @@ public class AltosSiteMapTile extends JLayeredPane { public AltosSiteMapTile(int x_tile_offset, int y_tile_offset) { setPreferredSize(new Dimension(px_size, px_size)); - mapLabel = new JLabel(); + mapLabel = new AltosSiteMapLabel(); fillLabel(mapLabel, Color.GRAY); mapLabel.setOpaque(true); mapLabel.setBounds(0, 0, px_size, px_size); diff --git a/ao-tools/altosui/Makefile.am b/ao-tools/altosui/Makefile.am index 41afdf27..334608f6 100644 --- a/ao-tools/altosui/Makefile.am +++ b/ao-tools/altosui/Makefile.am @@ -63,6 +63,7 @@ altosui_JAVA = \ AltosSerialInUseException.java \ AltosSerialMonitor.java \ AltosSiteMap.java \ + AltosSiteMapLabel.java \ AltosSiteMapTile.java \ AltosState.java \ AltosTelemetry.java \