diff options
| author | Anthony Towns <aj@erisian.com.au> | 2010-11-21 00:07:16 +1000 | 
|---|---|---|
| committer | Anthony Towns <aj@erisian.com.au> | 2010-11-21 00:07:16 +1000 | 
| commit | 25ffe1cc7823895886b4777f310b4bda1c80133b (patch) | |
| tree | de4f55824a3d1fd5c8c3ea070dceb8f7a109f7e6 | |
| parent | 20f714bbe3137de8fb7491b39985021fd1774930 (diff) | |
AltosSiteMap: automatic fetching of map data
| -rw-r--r-- | ao-tools/altosui/AltosSiteMapLabel.java | 142 | ||||
| -rw-r--r-- | ao-tools/altosui/AltosSiteMapTile.java | 32 | ||||
| -rw-r--r-- | ao-tools/altosui/Makefile.am | 1 | 
3 files changed, 147 insertions, 28 deletions
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 <aj@erisian.com.au> + * + * 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 \  | 
