diff options
Diffstat (limited to 'ao-tools/altosui')
| -rw-r--r-- | ao-tools/altosui/AltosSiteMap.java | 463 | ||||
| -rw-r--r-- | ao-tools/altosui/AltosSiteMapCache.java | 126 | ||||
| -rw-r--r-- | ao-tools/altosui/AltosSiteMapTile.java | 196 | 
3 files changed, 393 insertions, 392 deletions
diff --git a/ao-tools/altosui/AltosSiteMap.java b/ao-tools/altosui/AltosSiteMap.java index a241cbd0..5f5e30f0 100644 --- a/ao-tools/altosui/AltosSiteMap.java +++ b/ao-tools/altosui/AltosSiteMap.java @@ -33,236 +33,237 @@ import java.awt.geom.Point2D;  import java.awt.geom.Line2D;  public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { -    // max vertical step in a tile in naut. miles -    static final double tile_size_nmi = 1.0;  - -    static final int px_size = 512; - -    private static Point2D.Double translatePoint(Point2D.Double p,  -            Point2D.Double d)  -    { -        return new Point2D.Double(p.x + d.x, p.y + d.y); -    } - -    static class LatLng { -        public double lat, lng; -        public LatLng(double lat, double lng) { -            this.lat = lat; -            this.lng = lng; -        } -    } - -    // based on google js -    //  http://maps.gstatic.com/intl/en_us/mapfiles/api-3/2/10/main.js -    // search for fromLatLngToPoint and fromPointToLatLng -    private static Point2D.Double pt(LatLng latlng, int zoom) { -        double scale_x = 256/360.0 * Math.pow(2, zoom); -        double scale_y = 256/(2.0*Math.PI) * Math.pow(2, zoom); -        return pt(latlng, scale_x, scale_y); -    } - -    private static Point2D.Double pt(LatLng latlng,  -            double scale_x, double scale_y) -    { -        Point2D.Double res = new Point2D.Double(); -        double e; - -        res.x = latlng.lng * scale_x; - -        e = Math.sin(Math.toRadians(latlng.lat)); -        e = Math.max(e,-(1-1.0E-15)); -        e = Math.min(e,  1-1.0E-15 ); - -        res.y = 0.5*Math.log((1+e)/(1-e))*-scale_y; -        return res; -    } - -    static private LatLng latlng(Point2D.Double pt,  -            double scale_x, double scale_y) -    { -        double lat, lng; -        double rads; - -        lng = pt.x/scale_x; -        rads = 2 * Math.atan(Math.exp(-pt.y/scale_y)); -        lat = Math.toDegrees(rads - Math.PI/2); -                                                                     -        return new LatLng(lat,lng); -    } - -    int zoom; -    double scale_x, scale_y; - -    private Point2D.Double pt(double lat, double lng) { -        return pt(new LatLng(lat, lng), scale_x, scale_y); -    } - -    private LatLng latlng(double x, double y) { -        return latlng(new Point2D.Double(x,y), scale_x, scale_y); -    } -    private LatLng latlng(Point2D.Double pt) { -        return latlng(pt, scale_x, scale_y); -    } - -    AltosSiteMapTile [] mapTiles = new AltosSiteMapTile[9]; -    Point2D.Double [] tileOffset = new Point2D.Double[9]; - -    private Point2D.Double getBaseLocation(double lat, double lng) { -        Point2D.Double locn, north_step; - -        zoom = 2; -        // stupid loop structure to please Java's control flow analysis -        do { -            zoom++; -            scale_x = 256/360.0 * Math.pow(2, zoom); -            scale_y = 256/(2.0*Math.PI) * Math.pow(2, zoom); -            locn = pt(lat, lng); -            north_step = pt(lat+tile_size_nmi/60.0, lng); -            if (locn.y - north_step.y > px_size) -                break; -        } while (zoom < 22); -        locn.x = -px_size * Math.floor(locn.x/px_size); -        locn.y = -px_size * Math.floor(locn.y/px_size); -        return locn; -    } - -    public void reset() { -        // nothing -    } - -    private void bgLoadMap(final int i,  -            final File pngfile, final String pngurl)  -    { -        Thread thread = new Thread() { -            public void run() { -                ImageIcon res; -                res = AltosSiteMapCache.fetchAndLoadMap(pngfile, pngurl); -                if (res != null) { -                    mapTiles[i].loadMap(res); -                } else { -                    System.out.printf("# Failed to fetch file %s\n", pngfile); -                    System.out.printf(" wget -O '%s' ''\n", pngfile, pngurl); -                } -            } -        }; -        thread.start(); -    } -  -    public static void prefetchMaps(double lat, double lng, int w, int h) { -        AltosPreferences.init(null); - -        AltosSiteMap asm = new AltosSiteMap(true); -        Point2D.Double c = asm.getBaseLocation(lat, lng); -        Point2D.Double p = new Point2D.Double(); -        Point2D.Double p2; -        int dx = -w/2, dy = -h/2; -        for (int y = dy; y < h+dy; y++) { -            for (int x = dx; x < w+dx; x++) { -                LatLng map_latlng = asm.latlng( -                        -c.x + x*px_size + px_size/2,  -                        -c.y + y*px_size + px_size/2); -                File pngfile = asm.MapFile(map_latlng.lat, map_latlng.lng); -                String pngurl = asm.MapURL(map_latlng.lat, map_latlng.lng); -                if (pngfile.exists()) { -                    System.out.printf("Already have %s\n", pngfile); -                } else if (AltosSiteMapCache.fetchMap(pngfile, pngurl)) { -                    System.out.printf("Fetched map %s\n", pngfile); -                } else { -                    System.out.printf("# Failed to fetch file %s\n", pngfile); -                    System.out.printf(" wget -O '%s' ''\n", pngfile, pngurl); -                } -            } -        } -    } - -    private void initMaps(double lat, double lng) { -        Point2D.Double c = getBaseLocation(lat, lng); -        Point2D.Double p = new Point2D.Double(); - -        for (int i = 0; i < 9; i++) { -            int x = i%3 - 1, y = i/3 - 1; - -            tileOffset[i] = new Point2D.Double( -                    c.x - x*px_size, p.y = c.y - y*px_size); -            LatLng map_latlng = latlng( -                    -tileOffset[i].x+px_size/2,  -                    -tileOffset[i].y+px_size/2); - -            File pngfile = MapFile(map_latlng.lat, map_latlng.lng); -            String pngurl = MapURL(map_latlng.lat, map_latlng.lng); -            bgLoadMap(i, pngfile, pngurl); -        } -    }  -     -    private File MapFile(double lat, double lng) { -        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 String MapURL(double lat, double lng) { -        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); -    } - -    boolean initialised = false; -    public void show(AltosState state, int crc_errors) { -        // if insufficient gps data, nothing to update -        if (!state.gps_ready) { -            if (state.pad_lat == 0 && state.pad_lon == 0) -                return; -            if (state.ngps < 3) -                return; -        } - -        if (!initialised) { -            initMaps(state.pad_lat, state.pad_lon); -            initialised = true; -        } - -        Point2D.Double pt = pt(state.gps.lat, state.gps.lon); -        for (int x = 0; x < mapTiles.length; x++) { -            mapTiles[x].show(state, crc_errors,  -                    translatePoint(pt, tileOffset[x])); -        } -    } - -    private AltosSiteMap(boolean knowWhatYouAreDoing) { -        if (!knowWhatYouAreDoing) { -            throw new RuntimeException("Arggh."); -        } -    } - -    public AltosSiteMap() { -        JComponent comp = new JComponent() { -            GrabNDrag scroller = new GrabNDrag(this); -            { -                addMouseMotionListener(scroller); -                addMouseListener(scroller); -                setAutoscrolls(true); -            } -        }; - -        GridBagLayout layout = new GridBagLayout(); -        comp.setLayout(layout); - -        GridBagConstraints c = new GridBagConstraints(); -        c.anchor = GridBagConstraints.CENTER; -        c.fill = GridBagConstraints.BOTH; - -        // put some space between the map tiles, debugging only -        // c.insets = new Insets(5, 5, 5, 5); -        for (int x = 0; x < 9; x++) { -            c.gridx = x % 3; c.gridy = x / 3; -            mapTiles[x] = new AltosSiteMapTile(px_size); -            layout.setConstraints(mapTiles[x], c); -            comp.add(mapTiles[x]); -        } -        setViewportView(comp); -        setPreferredSize(new Dimension(500,200)); -    } +	// max vertical step in a tile in naut. miles +	static final double tile_size_nmi = 1.0; + +	static final int px_size = 512; + +	private static Point2D.Double translatePoint(Point2D.Double p, +			Point2D.Double d) +	{ +		return new Point2D.Double(p.x + d.x, p.y + d.y); +	} + +	static class LatLng { +		public double lat, lng; +		public LatLng(double lat, double lng) { +			this.lat = lat; +			this.lng = lng; +		} +	} + +	// based on google js +	//  http://maps.gstatic.com/intl/en_us/mapfiles/api-3/2/10/main.js +	// search for fromLatLngToPoint and fromPointToLatLng +	private static Point2D.Double pt(LatLng latlng, int zoom) { +		double scale_x = 256/360.0 * Math.pow(2, zoom); +		double scale_y = 256/(2.0*Math.PI) * Math.pow(2, zoom); +		return pt(latlng, scale_x, scale_y); +	} + +	private static Point2D.Double pt(LatLng latlng, +					 double scale_x, double scale_y) +	{ +		Point2D.Double res = new Point2D.Double(); +		double e; + +		res.x = latlng.lng * scale_x; + +		e = Math.sin(Math.toRadians(latlng.lat)); +		e = Math.max(e,-(1-1.0E-15)); +		e = Math.min(e,  1-1.0E-15 ); + +		res.y = 0.5*Math.log((1+e)/(1-e))*-scale_y; +		return res; +	} + +	static private LatLng latlng(Point2D.Double pt, +				     double scale_x, double scale_y) +	{ +		double lat, lng; +		double rads; + +		lng = pt.x/scale_x; +		rads = 2 * Math.atan(Math.exp(-pt.y/scale_y)); +		lat = Math.toDegrees(rads - Math.PI/2); + +		return new LatLng(lat,lng); +	} + +	int zoom; +	double scale_x, scale_y; + +	private Point2D.Double pt(double lat, double lng) { +		return pt(new LatLng(lat, lng), scale_x, scale_y); +	} + +	private LatLng latlng(double x, double y) { +		return latlng(new Point2D.Double(x,y), scale_x, scale_y); +	} +	private LatLng latlng(Point2D.Double pt) { +		return latlng(pt, scale_x, scale_y); +	} + +	AltosSiteMapTile [] mapTiles = new AltosSiteMapTile[9]; +	Point2D.Double [] tileOffset = new Point2D.Double[9]; + +	private Point2D.Double getBaseLocation(double lat, double lng) { +		Point2D.Double locn, north_step; + +		zoom = 2; +		// stupid loop structure to please Java's control flow analysis +		do { +			zoom++; +			scale_x = 256/360.0 * Math.pow(2, zoom); +			scale_y = 256/(2.0*Math.PI) * Math.pow(2, zoom); +			locn = pt(lat, lng); +			north_step = pt(lat+tile_size_nmi/60.0, lng); +			if (locn.y - north_step.y > px_size) +				break; +		} while (zoom < 22); +		locn.x = -px_size * Math.floor(locn.x/px_size); +		locn.y = -px_size * Math.floor(locn.y/px_size); +		return locn; +	} + +	public void reset() { +		// nothing +	} + +	private void bgLoadMap(final int i, +			       final File pngfile, final String pngurl) +	{ +		Thread thread = new Thread() { +			public void run() { +				ImageIcon res; +				res = AltosSiteMapCache.fetchAndLoadMap(pngfile, pngurl); +				if (res != null) { +					mapTiles[i].loadMap(res); +				} else { +					System.out.printf("# Failed to fetch file %s\n", pngfile); +					System.out.printf(" wget -O '%s' ''\n", pngfile, pngurl); +				} +			} +		}; +		thread.start(); +	} + +	public static void prefetchMaps(double lat, double lng, int w, int h) { +		AltosPreferences.init(null); + +		AltosSiteMap asm = new AltosSiteMap(true); +		Point2D.Double c = asm.getBaseLocation(lat, lng); +		Point2D.Double p = new Point2D.Double(); +		Point2D.Double p2; +		int dx = -w/2, dy = -h/2; +		for (int y = dy; y < h+dy; y++) { +			for (int x = dx; x < w+dx; x++) { +				LatLng map_latlng = asm.latlng( +							    -c.x + x*px_size + px_size/2, +							    -c.y + y*px_size + px_size/2); +				File pngfile = asm.MapFile(map_latlng.lat, map_latlng.lng); +				String pngurl = asm.MapURL(map_latlng.lat, map_latlng.lng); +				if (pngfile.exists()) { +					System.out.printf("Already have %s\n", pngfile); +				} else if (AltosSiteMapCache.fetchMap(pngfile, pngurl)) { +					System.out.printf("Fetched map %s\n", pngfile); +				} else { +					System.out.printf("# Failed to fetch file %s\n", pngfile); +					System.out.printf(" wget -O '%s' ''\n", pngfile, pngurl); +				} +			} +		} +	} + +	private void initMaps(double lat, double lng) { +		Point2D.Double c = getBaseLocation(lat, lng); +		Point2D.Double p = new Point2D.Double(); + +		for (int i = 0; i < 9; i++) { +			int x = i%3 - 1, y = i/3 - 1; + +			tileOffset[i] = new Point2D.Double( +				c.x - x*px_size, p.y = c.y - y*px_size); +			LatLng map_latlng = latlng( +						    -tileOffset[i].x+px_size/2, +						    -tileOffset[i].y+px_size/2); + +			File pngfile = MapFile(map_latlng.lat, map_latlng.lng); +			String pngurl = MapURL(map_latlng.lat, map_latlng.lng); +			bgLoadMap(i, pngfile, pngurl); +		} +	} + +	private File MapFile(double lat, double lng) { +		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 String MapURL(double lat, double lng) { +		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); +	} + +	boolean initialised = false; +	public void show(AltosState state, int crc_errors) { +		// if insufficient gps data, nothing to update +		if (!state.gps_ready) { +			if (state.pad_lat == 0 && state.pad_lon == 0) +				return; +			if (state.ngps < 3) +				return; +		} + +		if (!initialised) { +			initMaps(state.pad_lat, state.pad_lon); +			initialised = true; +		} + +		Point2D.Double pt = pt(state.gps.lat, state.gps.lon); +		for (int x = 0; x < mapTiles.length; x++) { +			mapTiles[x].show(state, crc_errors, +					 translatePoint(pt, tileOffset[x])); +		} +	} + +	private AltosSiteMap(boolean knowWhatYouAreDoing) { +		if (!knowWhatYouAreDoing) { +			throw new RuntimeException("Arggh."); +		} +	} + +	public AltosSiteMap() { +		JComponent comp = new JComponent() { +			GrabNDrag scroller = new GrabNDrag(this); +			{ +				addMouseMotionListener(scroller); +				addMouseListener(scroller); +				setAutoscrolls(true); +			} +		}; + +		GridBagLayout layout = new GridBagLayout(); +		comp.setLayout(layout); + +		GridBagConstraints c = new GridBagConstraints(); +		c.anchor = GridBagConstraints.CENTER; +		c.fill = GridBagConstraints.BOTH; + +		// put some space between the map tiles, debugging only +		// c.insets = new Insets(5, 5, 5, 5); +		for (int x = 0; x < 9; x++) { +			c.gridx = x % 3; +			c.gridy = x / 3; +			mapTiles[x] = new AltosSiteMapTile(px_size); +			layout.setConstraints(mapTiles[x], c); +			comp.add(mapTiles[x]); +		} +		setViewportView(comp); +		setPreferredSize(new Dimension(500,200)); +	}  } diff --git a/ao-tools/altosui/AltosSiteMapCache.java b/ao-tools/altosui/AltosSiteMapCache.java index dbdcbf65..e9dbf8e6 100644 --- a/ao-tools/altosui/AltosSiteMapCache.java +++ b/ao-tools/altosui/AltosSiteMapCache.java @@ -31,73 +31,73 @@ import java.net.URL;  import java.net.URLConnection;  public class AltosSiteMapCache extends JLabel { -    public static boolean fetchMap(File file, String url) { -        URL u; -        try { -            u = new URL(url); -        } catch (java.net.MalformedURLException e) { -            return false; -        } +	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(); +		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; -    } +			if (offset != contentLength) { +				return false; +			} +		} catch (IOException e) { +			return false; +		} -    public static ImageIcon fetchAndLoadMap(File pngfile, String url) { -        if (!pngfile.exists()) { -            if (!fetchMap(pngfile, url)) { -                return null; -            } -        } -        return loadMap(pngfile, url); -    } +		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 static ImageIcon loadMap(File pngfile, String url) { -        if (!pngfile.exists()) { -            return null; -        } +	public static ImageIcon fetchAndLoadMap(File pngfile, String url) { +		if (!pngfile.exists()) { +			if (!fetchMap(pngfile, url)) { +				return null; +			} +		} +		return loadMap(pngfile, url); +	} -        try { -            return new ImageIcon(ImageIO.read(pngfile)); -        } catch (IOException e) {  -            System.out.printf("# IO error trying to load %s\n", pngfile); -            return null; -        } -    } +	public static ImageIcon loadMap(File pngfile, String url) { +		if (!pngfile.exists()) { +			return null; +		} + +		try { +			return new ImageIcon(ImageIO.read(pngfile)); +		} catch (IOException e) { +			System.out.printf("# IO error trying to load %s\n", pngfile); +			return null; +		} +	}  } diff --git a/ao-tools/altosui/AltosSiteMapTile.java b/ao-tools/altosui/AltosSiteMapTile.java index de28fc8b..8aee86c1 100644 --- a/ao-tools/altosui/AltosSiteMapTile.java +++ b/ao-tools/altosui/AltosSiteMapTile.java @@ -32,103 +32,103 @@ import java.awt.geom.Point2D;  import java.awt.geom.Line2D;  public class AltosSiteMapTile extends JLayeredPane { -    Point2D.Double coord_pt; -    Point2D.Double last_pt; - -    JLabel mapLabel; -    JLabel draw; -    Graphics2D g2d; - -    public void loadMap(ImageIcon icn) { -        mapLabel.setIcon(icn); -    } - -    static Color stateColors[] = { -        Color.WHITE,  // startup -        Color.WHITE,  // idle -        Color.WHITE,  // pad -        Color.RED,    // boost -        Color.PINK,   // fast -        Color.YELLOW, // coast -        Color.CYAN,   // drogue -        Color.BLUE,   // main -        Color.BLACK   // landed -    }; - -    boolean drawn_landed_circle = false; -    boolean drawn_boost_circle = false; -    public void show(AltosState state, int crc_errors, Point2D.Double pt) { -        if (last_pt == null) { -            // setLocation(state.pad_lat, state.pad_lon); -            // loadMap(); -            last_pt = pt; -        } - -        if (pt != last_pt) { -            if (0 <= state.state && state.state < stateColors.length) { -                g2d.setColor(stateColors[state.state]); -            } -            g2d.draw(new Line2D.Double(last_pt, pt)); -        } - -        int px_size = getWidth(); -        if (0 <= pt.x && pt.x < px_size) { -            if (0 <= pt.y && pt.y < px_size) { -                int dx = 500, dy = 250; -                if (state.state > 2) { -                    dx = Math.min(200, 20 + (int) Math.abs(last_pt.x - pt.x)); -                    dy = Math.min(100, 10 + (int) Math.abs(last_pt.y - pt.y)); -                } -                Rectangle r = new Rectangle((int)pt.x-dx, (int)pt.y-dy,  -                                            dx*2, dy*2); -                scrollRectToVisible(r); -            } -        } - -        if (state.state == 3 && !drawn_boost_circle) { -            drawn_boost_circle = true; -            g2d.setColor(Color.RED); -            g2d.drawOval((int)last_pt.x-5, (int)last_pt.y-5, 10, 10); -            g2d.drawOval((int)last_pt.x-20, (int)last_pt.y-20, 40, 40); -            g2d.drawOval((int)last_pt.x-35, (int)last_pt.y-35, 70, 70); -        } -        if (state.state == 8 && !drawn_landed_circle) { -            drawn_landed_circle = true; -            g2d.setColor(Color.BLACK); -            g2d.drawOval((int)pt.x-5, (int)pt.y-5, 10, 10); -            g2d.drawOval((int)pt.x-20, (int)pt.y-20, 40, 40); -            g2d.drawOval((int)pt.x-35, (int)pt.y-35, 70, 70); -        } - -        last_pt = pt; -        repaint(); -    } - -    public static Graphics2D fillLabel(JLabel l, Color c, int px_size) { -        BufferedImage img = new BufferedImage(px_size, px_size, -                BufferedImage.TYPE_INT_ARGB); -        Graphics2D g = img.createGraphics(); -        g.setColor(c); -        g.fillRect(0, 0, px_size, px_size); -        l.setIcon(new ImageIcon(img)); -        return g; -    } - -    public AltosSiteMapTile(int px_size) { -        setPreferredSize(new Dimension(px_size, px_size)); - -        mapLabel = new JLabel(); -        fillLabel(mapLabel, Color.GRAY, px_size); -        mapLabel.setOpaque(true); -        mapLabel.setBounds(0, 0, px_size, px_size); -        add(mapLabel, new Integer(0)); - -        draw = new JLabel(); -        g2d = fillLabel(draw, new Color(127, 127, 127, 0), px_size); -        draw.setBounds(0, 0, px_size, px_size); -        draw.setOpaque(false); - -        add(draw, new Integer(1)); -    } +	Point2D.Double coord_pt; +	Point2D.Double last_pt; + +	JLabel mapLabel; +	JLabel draw; +	Graphics2D g2d; + +	public void loadMap(ImageIcon icn) { +		mapLabel.setIcon(icn); +	} + +	static Color stateColors[] = { +		Color.WHITE,  // startup +		Color.WHITE,  // idle +		Color.WHITE,  // pad +		Color.RED,    // boost +		Color.PINK,   // fast +		Color.YELLOW, // coast +		Color.CYAN,   // drogue +		Color.BLUE,   // main +		Color.BLACK   // landed +	}; + +	boolean drawn_landed_circle = false; +	boolean drawn_boost_circle = false; +	public void show(AltosState state, int crc_errors, Point2D.Double pt) { +		if (last_pt == null) { +			// setLocation(state.pad_lat, state.pad_lon); +			// loadMap(); +			last_pt = pt; +		} + +		if (pt != last_pt) { +			if (0 <= state.state && state.state < stateColors.length) { +				g2d.setColor(stateColors[state.state]); +			} +			g2d.draw(new Line2D.Double(last_pt, pt)); +		} + +		int px_size = getWidth(); +		if (0 <= pt.x && pt.x < px_size) { +			if (0 <= pt.y && pt.y < px_size) { +				int dx = 500, dy = 250; +				if (state.state > 2) { +					dx = Math.min(200, 20 + (int) Math.abs(last_pt.x - pt.x)); +					dy = Math.min(100, 10 + (int) Math.abs(last_pt.y - pt.y)); +				} +				Rectangle r = new Rectangle((int)pt.x-dx, (int)pt.y-dy, +							    dx*2, dy*2); +				scrollRectToVisible(r); +			} +		} + +		if (state.state == 3 && !drawn_boost_circle) { +			drawn_boost_circle = true; +			g2d.setColor(Color.RED); +			g2d.drawOval((int)last_pt.x-5, (int)last_pt.y-5, 10, 10); +			g2d.drawOval((int)last_pt.x-20, (int)last_pt.y-20, 40, 40); +			g2d.drawOval((int)last_pt.x-35, (int)last_pt.y-35, 70, 70); +		} +		if (state.state == 8 && !drawn_landed_circle) { +			drawn_landed_circle = true; +			g2d.setColor(Color.BLACK); +			g2d.drawOval((int)pt.x-5, (int)pt.y-5, 10, 10); +			g2d.drawOval((int)pt.x-20, (int)pt.y-20, 40, 40); +			g2d.drawOval((int)pt.x-35, (int)pt.y-35, 70, 70); +		} + +		last_pt = pt; +		repaint(); +	} + +	public static Graphics2D fillLabel(JLabel l, Color c, int px_size) { +		BufferedImage img = new BufferedImage(px_size, px_size, +						      BufferedImage.TYPE_INT_ARGB); +		Graphics2D g = img.createGraphics(); +		g.setColor(c); +		g.fillRect(0, 0, px_size, px_size); +		l.setIcon(new ImageIcon(img)); +		return g; +	} + +	public AltosSiteMapTile(int px_size) { +		setPreferredSize(new Dimension(px_size, px_size)); + +		mapLabel = new JLabel(); +		fillLabel(mapLabel, Color.GRAY, px_size); +		mapLabel.setOpaque(true); +		mapLabel.setBounds(0, 0, px_size, px_size); +		add(mapLabel, new Integer(0)); + +		draw = new JLabel(); +		g2d = fillLabel(draw, new Color(127, 127, 127, 0), px_size); +		draw.setBounds(0, 0, px_size, px_size); +		draw.setOpaque(false); + +		add(draw, new Integer(1)); +	}  }  | 
