X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=ao-tools%2Faltosui%2FAltosSiteMap.java;h=0375128e1bfec7b014dcca63fea1b0f0395ede93;hp=50177d4e84b9a564c16bc64349a58cfd33af3b46;hb=a08b2a6363c194195db92029743f6612676373ce;hpb=8df185cd95cfecbed8272dd1275d077c5b45535b diff --git a/ao-tools/altosui/AltosSiteMap.java b/ao-tools/altosui/AltosSiteMap.java index 50177d4e..0375128e 100644 --- a/ao-tools/altosui/AltosSiteMap.java +++ b/ao-tools/altosui/AltosSiteMap.java @@ -33,8 +33,10 @@ 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; + // preferred vertical step in a tile in naut. miles + // will actually choose a step size between x and 2x, where this + // is 1.5x + static final double tile_size_nmi = 0.75; static final int px_size = 512; @@ -104,8 +106,18 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { return latlng(pt, scale_x, scale_y); } - AltosSiteMapTile [] mapTiles = new AltosSiteMapTile[9]; - Point2D.Double [] tileOffset = new Point2D.Double[9]; + HashMap mapTiles = new HashMap(); + Point2D.Double centre; + + private Point2D.Double tileCoordOffset(Point p) { + return new Point2D.Double(centre.x - p.x*px_size, + centre.y - p.y * px_size); + } + + private Point tileOffset(Point2D.Double p) { + return new Point((int)Math.floor((centre.x+p.x)/px_size), + (int)Math.floor((centre.y+p.y)/px_size)); + } private Point2D.Double getBaseLocation(double lat, double lng) { Point2D.Double locn, north_step; @@ -117,7 +129,7 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { 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); + north_step = pt(lat+tile_size_nmi*4/3/60.0, lng); if (locn.y - north_step.y > px_size) break; } while (zoom < 22); @@ -130,15 +142,16 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { // nothing } - private void bgLoadMap(final int i, + private void bgLoadMap(final AltosSiteMapTile tile, final File pngfile, final String pngurl) { + //System.out.printf("Loading/fetching map %s\n", pngfile); Thread thread = new Thread() { public void run() { ImageIcon res; res = AltosSiteMapCache.fetchAndLoadMap(pngfile, pngurl); if (res != null) { - mapTiles[i].loadMap(res); + tile.loadMap(res); } else { System.out.printf("# Failed to fetch file %s\n", pngfile); System.out.printf(" wget -O '%s' ''\n", pngfile, pngurl); @@ -152,15 +165,16 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { AltosPreferences.init(null); AltosSiteMap asm = new AltosSiteMap(true); - Point2D.Double c = asm.getBaseLocation(lat, lng); + asm.centre = 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); + -asm.centre.x + x*px_size + px_size/2, + -asm.centre.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()) { @@ -175,22 +189,21 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { } } - private void initMaps(double lat, double lng) { - Point2D.Double c = getBaseLocation(lat, lng); - Point2D.Double p = new Point2D.Double(); + private void initMap(AltosSiteMapTile tile, Point offset) { + Point2D.Double coord = tileCoordOffset(offset); + + LatLng map_latlng = latlng(px_size/2-coord.x, px_size/2-coord.y); - for (int i = 0; i < 9; i++) { - int x = i%3 - 1, y = i/3 - 1; + File pngfile = MapFile(map_latlng.lat, map_latlng.lng); + String pngurl = MapURL(map_latlng.lat, map_latlng.lng); + bgLoadMap(tile, pngfile, pngurl); + } - 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); + private void initMaps(double lat, double lng) { + centre = getBaseLocation(lat, lng); - File pngfile = MapFile(map_latlng.lat, map_latlng.lng); - String pngurl = MapURL(map_latlng.lat, map_latlng.lng); - bgLoadMap(i, pngfile, pngurl); + for (Point k : mapTiles.keySet()) { + initMap(mapTiles.get(k), k); } } @@ -209,12 +222,16 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { } boolean initialised = false; - public void show(AltosState state, int crc_errors) { + Point2D.Double last_pt = null; + int last_state = -1; + public void show(final AltosState state, final int crc_errors) { // if insufficient gps data, nothing to update - if (state.gps == null || !state.gps.locked) { - if (state.pad_lat == 0 && state.pad_lon == 0) - return; - if (state.ngps < 3) + if (state.gps == null) + return; + if (state.pad_lat == 0 && state.pad_lon == 0) + return; + if (!state.gps.locked) { + if (state.gps.nsat < 4) return; } @@ -223,11 +240,59 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { 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])); + final Point2D.Double pt = pt(state.gps.lat, state.gps.lon); + if (last_pt == pt && last_state == state.state) + return; + + if (last_pt == null) { + last_pt = pt; } + boolean in_any = false; + for (Point offset : mapTiles.keySet()) { + AltosSiteMapTile tile = mapTiles.get(offset); + Point2D.Double ref, lref; + ref = translatePoint(pt, tileCoordOffset(offset)); + lref = translatePoint(last_pt, tileCoordOffset(offset)); + tile.show(state, crc_errors, lref, ref); + if (0 <= ref.x && ref.x < px_size) + if (0 <= ref.y && ref.y < px_size) + in_any = true; + } + if (!in_any) { + final AltosSiteMapTile tile = new AltosSiteMapTile(px_size); + final Point offset = tileOffset(pt); + mapTiles.put(offset, tile); + + Point2D.Double ref, lref; + ref = translatePoint(pt, tileCoordOffset(offset)); + lref = translatePoint(last_pt, tileCoordOffset(offset)); + tile.show(state, crc_errors, lref, ref); + + initMap(tile, offset); + + SwingUtilities.invokeLater( new Runnable() { + public void run() { + addTileAt(tile, offset); + setViewportView(comp); + } + } ); + } + last_pt = pt; + last_state = state.state; + } + + private void addTileAt(AltosSiteMapTile tile, Point offset) { + 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); + // + c.gridx = offset.x + 100; + c.gridy = offset.y + 100; + layout.setConstraints(tile, c); + comp.add(tile); } private AltosSiteMap(boolean knowWhatYouAreDoing) { @@ -236,8 +301,11 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { } } + JComponent comp; + private GridBagLayout layout; + public AltosSiteMap() { - JComponent comp = new JComponent() { + comp = new JComponent() { GrabNDrag scroller = new GrabNDrag(this); { addMouseMotionListener(scroller); @@ -246,21 +314,16 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { } }; - GridBagLayout layout = new 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]); + for (int x = -1; x <= 1; x++) { + for (int y = -1; y <= 1; y++) { + AltosSiteMapTile t = new AltosSiteMapTile(px_size); + Point offset = new Point(x, y); + mapTiles.put(offset, t); + addTileAt(t, offset); + } } setViewportView(comp); setPreferredSize(new Dimension(500,200));