X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=ao-tools%2Faltosui%2FAltosSiteMap.java;h=d4a4cbf43dbaa66b7c0c69ca6da2be09bef08e5c;hp=25450e7eac02fb65ec4408a15e870ac3c50d9dc8;hb=357826aa9c7b42c59f5d52b8eb016d73b6da0c7f;hpb=c3994dd82d489289ebc99ff9c5fa88f560c023ac diff --git a/ao-tools/altosui/AltosSiteMap.java b/ao-tools/altosui/AltosSiteMap.java index 25450e7e..d4a4cbf4 100644 --- a/ao-tools/altosui/AltosSiteMap.java +++ b/ao-tools/altosui/AltosSiteMap.java @@ -40,6 +40,8 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { static final int px_size = 512; + static final int MAX_TILE_DELTA = 100; + private static Point2D.Double translatePoint(Point2D.Double p, Point2D.Double d) { @@ -106,15 +108,10 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { return latlng(pt, scale_x, scale_y); } - Vector mapTiles = new Vector(); + HashMap mapTiles = new HashMap(); Point2D.Double centre; - private Point tileOffset(AltosSiteMapTile tile) { - GridBagConstraints c = layout.getConstraints(tile); - return new Point(c.gridx - 100, c.gridy - 100); - } - private Point2D.Double tileCoordOffset(AltosSiteMapTile tile) { - Point p = tileOffset(tile); + private Point2D.Double tileCoordOffset(Point p) { return new Point2D.Double(centre.x - p.x*px_size, centre.y - p.y * px_size); } @@ -194,10 +191,10 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { } } - private void initMap(AltosSiteMapTile tile) { - Point2D.Double offset = tileCoordOffset(tile); + private void initMap(AltosSiteMapTile tile, Point offset) { + Point2D.Double coord = tileCoordOffset(offset); - LatLng map_latlng = latlng(px_size/2-offset.x, px_size/2-offset.y); + LatLng map_latlng = latlng(px_size/2-coord.x, px_size/2-coord.y); File pngfile = MapFile(map_latlng.lat, map_latlng.lng); String pngurl = MapURL(map_latlng.lat, map_latlng.lng); @@ -207,8 +204,8 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { private void initMaps(double lat, double lng) { centre = getBaseLocation(lat, lng); - for (AltosSiteMapTile tile : mapTiles) { - initMap(tile); + for (Point k : mapTiles.keySet()) { + initMap(mapTiles.get(k), k); } } @@ -229,23 +226,26 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { boolean initialised = false; Point2D.Double last_pt = null; int last_state = -1; - public void show(AltosState state, int crc_errors) { + public void show(final AltosState state, final int crc_errors) { // if insufficient gps data, nothing to update if (state.gps == null) return; - if (!state.gps.locked) { - if (state.pad_lat == 0 && state.pad_lon == 0) - return; - if (state.gps.nsat < 4) - return; - } + if (!state.gps.locked && state.gps.nsat < 4) + return; if (!initialised) { - initMaps(state.pad_lat, state.pad_lon); - initialised = true; + if (state.pad_lat != 0 || state.pad_lon != 0) { + initMaps(state.pad_lat, state.pad_lon); + initialised = true; + } else if (state.gps.lat != 0 || state.gps.lon != 0) { + initMaps(state.gps.lat, state.gps.lon); + initialised = true; + } else { + return; + } } - Point2D.Double pt = pt(state.gps.lat, state.gps.lon); + final Point2D.Double pt = pt(state.gps.lat, state.gps.lon); if (last_pt == pt && last_state == state.state) return; @@ -253,44 +253,115 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { last_pt = pt; } boolean in_any = false; - for (AltosSiteMapTile tile : mapTiles) { + for (Point offset : mapTiles.keySet()) { + AltosSiteMapTile tile = mapTiles.get(offset); Point2D.Double ref, lref; - ref = translatePoint(pt, tileCoordOffset(tile)); - lref = translatePoint(last_pt, tileCoordOffset(tile)); + 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; } + + Point offset = tileOffset(pt); if (!in_any) { - AltosSiteMapTile tile = addTileAt(tileOffset(pt)); Point2D.Double ref, lref; - ref = translatePoint(pt, tileCoordOffset(tile)); - lref = translatePoint(last_pt, tileCoordOffset(tile)); - initMap(tile); - setViewportView(comp); + ref = translatePoint(pt, tileCoordOffset(offset)); + lref = translatePoint(last_pt, tileCoordOffset(offset)); + + AltosSiteMapTile tile = createTile(offset); tile.show(state, crc_errors, lref, ref); + initMap(tile, offset); + finishTileLater(tile, offset); } + + scrollRocketToVisible(pt); + + if (offset != tileOffset(last_pt)) { + ensureTilesAround(offset); + } + last_pt = pt; last_state = state.state; } - private AltosSiteMapTile addTileAt(Point offset) { + private AltosSiteMapTile createTile(Point offset) { + AltosSiteMapTile tile = new AltosSiteMapTile(px_size); + mapTiles.put(offset, tile); + return tile; + } + private void finishTileLater(final AltosSiteMapTile tile, + final Point offset) + { + SwingUtilities.invokeLater( new Runnable() { + public void run() { + addTileAt(tile, offset); + } + } ); + } + + private void ensureTilesAround(Point base_offset) { + for (int x = -1; x <= 1; x++) { + for (int y = -1; y <= 1; y++) { + Point offset = new Point(base_offset.x + x, base_offset.y + y); + if (mapTiles.containsKey(offset)) + continue; + AltosSiteMapTile tile = createTile(offset); + initMap(tile, offset); + finishTileLater(tile, offset); + } + } + } + + private Point topleft = new Point(0,0); + private void scrollRocketToVisible(Point2D.Double pt) { + Rectangle r = comp.getVisibleRect(); + Point2D.Double copt = translatePoint(pt, tileCoordOffset(topleft)); + int dx = (int)copt.x - r.width/2 - r.x; + int dy = (int)copt.y - r.height/2 - r.y; + if (Math.abs(dx) > r.width/4 || Math.abs(dy) > r.height/4) { + r.x += dx; + r.y += dy; + comp.scrollRectToVisible(r); + } + } + + private void addTileAt(AltosSiteMapTile tile, Point offset) { + if (Math.abs(offset.x) >= MAX_TILE_DELTA || + Math.abs(offset.y) >= MAX_TILE_DELTA) + { + System.out.printf("Rocket too far away from pad (tile %d,%d)\n", + offset.x, offset.y); + return; + } + + boolean review = false; + Rectangle r = comp.getVisibleRect(); + if (offset.x < topleft.x) { + r.x += (topleft.x - offset.x) * px_size; + topleft.x = offset.x; + review = true; + } + if (offset.y < topleft.y) { + r.y += (topleft.y - offset.y) * px_size; + topleft.y = offset.y; + review = true; + } 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); - // - AltosSiteMapTile t = new AltosSiteMapTile(px_size); - mapTiles.add(t); - c.gridx = offset.x + 100; - c.gridy = offset.y + 100; - layout.setConstraints(t, c); - comp.add(t); - - return t; + + c.gridx = offset.x + MAX_TILE_DELTA; + c.gridy = offset.y + MAX_TILE_DELTA; + layout.setConstraints(tile, c); + + comp.add(tile); + if (review) { + comp.scrollRectToVisible(r); + } } private AltosSiteMap(boolean knowWhatYouAreDoing) { @@ -299,25 +370,19 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { } } - JComponent comp; - private GridBagLayout layout; + JComponent comp = new JComponent() { }; + private GridBagLayout layout = new GridBagLayout(); public AltosSiteMap() { - comp = new JComponent() { - GrabNDrag scroller = new GrabNDrag(this); - { - addMouseMotionListener(scroller); - addMouseListener(scroller); - setAutoscrolls(true); - } - }; + GrabNDrag scroller = new GrabNDrag(comp); - layout = new GridBagLayout(); comp.setLayout(layout); for (int x = -1; x <= 1; x++) { for (int y = -1; y <= 1; y++) { - addTileAt(new Point(x, y)); + Point offset = new Point(x, y); + AltosSiteMapTile t = createTile(offset); + addTileAt(t, offset); } } setViewportView(comp);