altosdroid: Display online/offline maps in same tab
[fw/altos] / altosdroid / src / org / altusmetrum / AltosDroid / TabMapOffline.java
index 31acda75a8bc613690d01ef2694b284ecc750a7a..26e04c8392a1342672979264b85ebef1ce79b01a 100644 (file)
@@ -17,7 +17,7 @@
 
 package org.altusmetrum.AltosDroid;
 
-import java.util.Arrays;
+import java.util.*;
 import java.io.*;
 
 import org.altusmetrum.altoslib_7.*;
@@ -32,26 +32,9 @@ import android.widget.*;
 import android.location.Location;
 import android.content.*;
 
-public class TabMapOffline extends AltosDroidTab implements AltosMapInterface {
-
-       AltosDroid mAltosDroid;
-
-       AltosMap map;
+public class TabMapOffline extends AltosDroidTab {
 
        AltosLatLon     here;
-       AltosLatLon     pad;
-
-       Canvas  canvas;
-       Paint   paint;
-
-       Bitmap  pad_bitmap;
-       int     pad_off_x, pad_off_y;
-       Bitmap  rocket_bitmap;
-       int     rocket_off_x, rocket_off_y;
-       Bitmap  here_bitmap;
-       int     here_off_x, here_off_y;
-
-       private boolean pad_set;
 
        private TextView mDistanceView;
        private TextView mBearingView;
@@ -59,350 +42,14 @@ public class TabMapOffline extends AltosDroidTab implements AltosMapInterface {
        private TextView mTargetLongitudeView;
        private TextView mReceiverLatitudeView;
        private TextView mReceiverLongitudeView;
-
-       private double mapAccuracy = -1;
-
-       int     stroke_width = 20;
-
-       private void draw_bitmap(AltosLatLon lat_lon, Bitmap bitmap, int off_x, int off_y) {
-               if (lat_lon != null) {
-                       AltosPointInt pt = new AltosPointInt(map.transform.screen(lat_lon));
-
-                       canvas.drawBitmap(bitmap, pt.x - off_x, pt.y - off_y, paint);
-               }
-       }
-
-       class MapView extends View implements ScaleGestureDetector.OnScaleGestureListener {
-
-               ScaleGestureDetector    scale_detector;
-               boolean                 scaling;
-
-               private void draw_positions() {
-                       if (map.last_position != null && here != null) {
-                               AltosPointDouble        rocket_screen = map.transform.screen(map.last_position);
-                               AltosPointDouble        here_screen = map.transform.screen(here);
-                               paint.setColor(0xff8080ff);
-                               canvas.drawLine((float) rocket_screen.x, (float) rocket_screen.y,
-                                               (float) here_screen.x, (float) here_screen.y, paint);
-                       }
-                       draw_bitmap(pad, pad_bitmap, pad_off_x, pad_off_y);
-                       draw_bitmap(map.last_position, rocket_bitmap, rocket_off_x, rocket_off_y);
-                       draw_bitmap(here, here_bitmap, here_off_x, here_off_y);
-               }
-
-               protected void onDraw(Canvas view_canvas) {
-                       canvas = view_canvas;
-                       paint = new Paint(Paint.ANTI_ALIAS_FLAG);
-                       paint.setStrokeWidth(stroke_width);
-                       paint.setStrokeCap(Paint.Cap.ROUND);
-                       paint.setStrokeJoin(Paint.Join.ROUND);
-                       map.paint();
-                       draw_positions();
-                       canvas = null;
-               }
-
-               public boolean onScale(ScaleGestureDetector detector) {
-                       float   f = detector.getScaleFactor();
-                       AltosDebug.debug("onScale %f\n", f);
-                       if (f <= 0.8) {
-                               map.set_zoom(map.get_zoom() - 1);
-                               return true;
-                       }
-                       if (f >= 1.2) {
-                               map.set_zoom(map.get_zoom() + 1);
-                               return true;
-                       }
-                       return false;
-               }
-
-               public boolean onScaleBegin(ScaleGestureDetector detector) {
-                       AltosDebug.debug("onScaleBegin %f\n", detector.getScaleFactor());
-                       return true;
-               }
-
-               public void onScaleEnd(ScaleGestureDetector detector) {
-                       AltosDebug.debug("onScaleEnd %f\n", detector.getScaleFactor());
-               }
-
-               @Override
-               public boolean dispatchTouchEvent(MotionEvent event) {
-                       scale_detector.onTouchEvent(event);
-
-                       if (scale_detector.isInProgress()) {
-                               scaling = true;
-                       }
-
-                       if (scaling) {
-                               if(AltosDebug.D) AltosDebug.debug("scale in progress\n");
-                               if (event.getAction() == MotionEvent.ACTION_UP) {
-                                       AltosDebug.debug("scale finished\n");
-                                       scaling = false;
-                               }
-                               return true;
-                       }
-
-                       if (event.getAction() == MotionEvent.ACTION_DOWN) {
-                               AltosDebug.debug("down event %g %g\n", event.getX(), event.getY());
-                               map.touch_start((int) event.getX(), (int) event.getY(), true);
-                       } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
-                               AltosDebug.debug("continue event %g %g\n", event.getX(), event.getY());
-                               map.touch_continue((int) event.getX(), (int) event.getY(), true);
-                       }
-                       return true;
-               }
-
-               public MapView(Context context) {
-                       super(context);
-                       scale_detector = new ScaleGestureDetector(this.getContext(), this);
-               }
-       }
-
-       class MapFragment extends Fragment {
-               MapView map_view;
-
-               public View onCreateView(LayoutInflater inflator, ViewGroup container, Bundle savedInstanceState) {
-                       map_view = new MapView(container.getContext());
-                       return map_view;
-               }
-
-               public MapFragment() {
-               }
-       }
-
-       MapFragment map_fragment;
-
-       /* AltosMapInterface */
-
-       static  final int       WHITE = 0xffffffff;
-       static  final int       RED   = 0xffff0000;
-       static  final int       PINK  = 0xffff8080;
-       static  final int       YELLOW= 0xffffff00;
-       static  final int       CYAN  = 0xff00ffff;
-       static  final int       BLUE  = 0xff0000ff;
-       static  final int       BLACK = 0xff000000;
-
-       public static final int stateColors[] = {
-               WHITE,  // startup
-               WHITE,  // idle
-               WHITE,  // pad
-               RED,    // boost
-               PINK,   // fast
-               YELLOW, // coast
-               CYAN,   // drogue
-               BLUE,   // main
-               BLACK,  // landed
-               BLACK,  // invalid
-               CYAN,   // stateless
-       };
-
-       class MapPath extends AltosMapPath {
-
-               boolean line_in(AltosPointDouble a, AltosPointDouble b) {
-                       final Rect bounds = canvas.getClipBounds();
-                       int left = (int) Math.floor (Math.min((float) a.x, (float) b.x) - stroke_width / 2.0f);
-                       int right = (int) Math.ceil(Math.max((float) a.x, (float) b.x) + stroke_width / 2.0f);
-                       int top = (int) Math.floor(Math.min((float) a.y, (float) b.y) - stroke_width / 2.0f);
-                       int bottom = (int) Math.ceil(Math.max((float) a.y, (float) b.y) + stroke_width / 2.0f);
-
-                       return left < bounds.right && bounds.left < right &&
-                               top < bounds.bottom && bounds.top < bottom;
-               }
-
-               public void paint(AltosMapTransform t) {
-                       AltosPointDouble        prev = null;
-                       int                     cur_color = paint.getColor();
-
-                       for (AltosMapPathPoint point : points) {
-                               AltosPointDouble        cur = t.screen(point.lat_lon);
-
-                               if (prev != null && line_in(prev, cur)) {
-                                       int color;
-                                       if (0 <= point.state && point.state < stateColors.length)
-                                               color = stateColors[point.state];
-                                       else
-                                               color = stateColors[AltosLib.ao_flight_invalid];
-                                       if (color != cur_color) {
-                                               paint.setColor(color);
-                                               cur_color = color;
-                                       }
-                                       canvas.drawLine((float) prev.x, (float) prev.y, (float) cur.x, (float) cur.y, paint);
-                               }
-                               prev = cur;
-                       }
-               }
-
-               public MapPath() {
-                       stroke_width = TabMapOffline.this.stroke_width;
-               }
-       }
-
-       public AltosMapPath new_path() {
-               return null;
-       }
-
-       class MapLine extends AltosMapLine {
-               public void paint(AltosMapTransform t) {
-               }
-
-               public MapLine() {
-               }
-       }
-
-       public AltosMapLine new_line() {
-               return null;
-       }
-
-       class MapImage implements AltosImage {
-               public Bitmap   bitmap;
-
-               public void flush() {
-                       if (bitmap != null) {
-                               bitmap.recycle();
-                               bitmap = null;
-                       }
-               }
-
-               public MapImage(File file) {
-                       bitmap = BitmapFactory.decodeFile(file.getPath());
-               }
-       }
-
-       public AltosImage load_image(File file) throws Exception {
-               return new MapImage(file);
-       }
-
-       class MapMark extends AltosMapMark {
-               public void paint(AltosMapTransform t) {
-               }
-
-               MapMark(double lat, double lon, int state) {
-                       super(lat, lon, state);
-               }
-       }
-
-       public AltosMapMark new_mark(double lat, double lon, int state) {
-               return new MapMark(lat, lon, state);
-       }
-
-       class MapTile extends AltosMapTile {
-               public void paint(AltosMapTransform t) {
-                       AltosPointInt           pt = new AltosPointInt(t.screen(upper_left));
-
-                       if (canvas.quickReject(pt.x, pt.y, pt.x + px_size, pt.y + px_size, Canvas.EdgeType.AA))
-                               return;
-
-                       AltosImage              altos_image = cache.get(this, store, px_size, px_size);
-
-                       MapImage                map_image = (MapImage) altos_image;
-
-                       Bitmap                  bitmap = null;
-
-                       if (map_image != null)
-                               bitmap = map_image.bitmap;
-
-                       if (bitmap != null) {
-                               canvas.drawBitmap(bitmap, pt.x, pt.y, paint);
-                       } else {
-                               paint.setColor(0xff808080);
-                               canvas.drawRect(pt.x, pt.y, pt.x + px_size, pt.y + px_size, paint);
-                               if (t.has_location()) {
-                                       String  message = null;
-                                       switch (status) {
-                                       case AltosMapTile.loading:
-                                               message = "Loading...";
-                                               break;
-                                       case AltosMapTile.bad_request:
-                                               message = "Internal error";
-                                               break;
-                                       case AltosMapTile.failed:
-                                               message = "Network error, check connection";
-                                               break;
-                                       case AltosMapTile.forbidden:
-                                               message = "Too many requests, try later";
-                                               break;
-                                       }
-                                       if (message != null) {
-                                               Rect    bounds = new Rect();
-                                               paint.getTextBounds(message, 0, message.length(), bounds);
-
-                                               int     width = bounds.right - bounds.left;
-                                               int     height = bounds.bottom - bounds.top;
-
-                                               float x = pt.x + px_size / 2.0f;
-                                               float y = pt.y + px_size / 2.0f;
-                                               x = x - width / 2.0f;
-                                               y = y + height / 2.0f;
-                                               paint.setColor(0xff000000);
-                                               canvas.drawText(message, 0, message.length(), x, y, paint);
-                                       }
-                               }
-                       }
-
-               }
-
-               public MapTile(AltosMapTileListener listener, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
-                       super(listener, upper_left, center, zoom, maptype, px_size, 2);
-               }
-
-       }
-
-       public AltosMapTile new_tile(AltosMapTileListener listener, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
-               return new MapTile(listener, upper_left, center, zoom, maptype, px_size);
-       }
-
-       public int width() {
-               if (map_fragment != null && map_fragment.map_view != null)
-                       return map_fragment.map_view.getWidth();
-               return 500;
-       }
-
-       public int height() {
-               if (map_fragment != null && map_fragment.map_view != null)
-                       return map_fragment.map_view.getHeight();
-               return 500;
-       }
-
-       public void repaint() {
-               this.getActivity().runOnUiThread(new Runnable() {
-                               public void run() {
-                                       if (map_fragment != null && map_fragment.map_view != null)
-                                               map_fragment.map_view.invalidate();
-                               }
-                       });
-       }
-
-       public void repaint(AltosRectangle t_damage) {
-               final AltosRectangle damage = t_damage;
-               this.getActivity().runOnUiThread(new Runnable() {
-                               public void run() {
-                                       if (map_fragment != null && map_fragment.map_view != null)
-                                               map_fragment.map_view.invalidate(damage.x, damage.y, damage.x + damage.width, damage.y + damage.height);
-                               }
-                       });
-       }
-
-       public void set_zoom_label(String label) {
-       }
+       private AltosMapOffline map_offline;
+       private AltosMapOnline map_online;
+       private View view;
+       private int map_source;
 
        @Override
        public void onAttach(Activity activity) {
                super.onAttach(activity);
-               mAltosDroid = (AltosDroid) activity;
-               mAltosDroid.registerTab(this);
-               pad_bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pad);
-               /* arrow at the bottom of the launchpad image */
-               pad_off_x = pad_bitmap.getWidth() / 2;
-               pad_off_y = pad_bitmap.getHeight();
-
-               rocket_bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.rocket);
-               /* arrow at the bottom of the rocket image */
-               rocket_off_x = rocket_bitmap.getWidth() / 2;
-               rocket_off_y = rocket_bitmap.getHeight();
-
-               here_bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_maps_indicator_current_position);
-               /* Center of the dot */
-               here_off_x = here_bitmap.getWidth() / 2;
-               here_off_y = here_bitmap.getHeight() / 2;
        }
 
        @Override
@@ -410,70 +57,65 @@ public class TabMapOffline extends AltosDroidTab implements AltosMapInterface {
                super.onCreate(savedInstanceState);
        }
 
+       private void make_offline_map() {
+       }
+
+       private void make_online_map() {
+               map_online = new AltosMapOnline(view.getContext());
+               map_online.onCreateView(altos_droid.map_type);
+       }
+
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-               View v = inflater.inflate(R.layout.tab_map, container, false);
-
-               map_fragment = new MapFragment();
-               map = new AltosMap(this);
-               mDistanceView  = (TextView)v.findViewById(R.id.distance_value);
-               mBearingView   = (TextView)v.findViewById(R.id.bearing_value);
-               mTargetLatitudeView  = (TextView)v.findViewById(R.id.target_lat_value);
-               mTargetLongitudeView = (TextView)v.findViewById(R.id.target_lon_value);
-               mReceiverLatitudeView  = (TextView)v.findViewById(R.id.receiver_lat_value);
-               mReceiverLongitudeView = (TextView)v.findViewById(R.id.receiver_lon_value);
-               return v;
+               view = inflater.inflate(R.layout.tab_map_offline, container, false);
+               int map_source = AltosDroidPreferences.map_source();
+
+               mDistanceView  = (TextView)view.findViewById(R.id.distance_value_offline);
+               mBearingView   = (TextView)view.findViewById(R.id.bearing_value_offline);
+               mTargetLatitudeView  = (TextView)view.findViewById(R.id.target_lat_value_offline);
+               mTargetLongitudeView = (TextView)view.findViewById(R.id.target_lon_value_offline);
+               mReceiverLatitudeView  = (TextView)view.findViewById(R.id.receiver_lat_value_offline);
+               mReceiverLongitudeView = (TextView)view.findViewById(R.id.receiver_lon_value_offline);
+               map_offline = (AltosMapOffline)view.findViewById(R.id.map_view_offline);
+               map_offline.onCreateView(altos_droid.map_type);
+               map_online = new AltosMapOnline(view.getContext());
+               map_online.onCreateView(altos_droid.map_type);
+               set_map_source(AltosDroidPreferences.map_source());
+               return view;
        }
 
        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
                super.onActivityCreated(savedInstanceState);
-               getChildFragmentManager().beginTransaction().add(R.id.map, map_fragment).commit();
+               if (map_online != null)
+                       getChildFragmentManager().beginTransaction().add(R.id.map_online, map_online.mMapFragment).commit();
        }
+
        @Override
        public void onDestroyView() {
                super.onDestroyView();
-
-               mAltosDroid.unregisterTab(this);
-               mAltosDroid = null;
-               map_fragment = null;
-
-//             Fragment fragment = (getFragmentManager().findFragmentById(R.id.map));
-//             FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
-//             ft.remove(fragment);
-//             ft.commit();
        }
 
-       private void setupMap() {
-       }
+       public String tab_name() { return "offmap"; }
 
        private void center(double lat, double lon, double accuracy) {
-               if (mapAccuracy < 0 || accuracy < mapAccuracy/10) {
-                       if (map != null)
-                               map.maybe_centre(lat, lon);
-                       mapAccuracy = accuracy;
-               }
+               if (map_offline != null)
+                       map_offline.center(lat, lon, accuracy);
+               if (map_online != null)
+                       map_online.center(lat, lon, accuracy);
        }
 
-       public String tab_name() { return "offmap"; }
-
-       public void show(AltosState state, AltosGreatCircle from_receiver, Location receiver) {
+       public void show(TelemetryState telem_state, AltosState state, AltosGreatCircle from_receiver, Location receiver) {
                if (from_receiver != null) {
                        mBearingView.setText(String.format("%3.0f°", from_receiver.bearing));
                        set_value(mDistanceView, AltosConvert.distance, 6, from_receiver.distance);
                }
 
                if (state != null) {
-                       map.show(state, null);
                        if (state.gps != null) {
                                mTargetLatitudeView.setText(AltosDroid.pos(state.gps.lat, "N", "S"));
                                mTargetLongitudeView.setText(AltosDroid.pos(state.gps.lon, "E", "W"));
-                               if (state.gps.locked && state.gps.nsat >= 4)
-                                       center (state.gps.lat, state.gps.lon, 10);
                        }
-                       if (state.pad_lat != AltosLib.MISSING && pad == null)
-                               pad = new AltosLatLon(state.pad_lat, state.pad_lon);
                }
 
                if (receiver != null) {
@@ -488,12 +130,41 @@ public class TabMapOffline extends AltosDroidTab implements AltosMapInterface {
                        mReceiverLongitudeView.setText(AltosDroid.pos(here.lon, "E", "W"));
                        center (here.lat, here.lon, accuracy);
                }
-
+               if (map_source == AltosDroidPreferences.MAP_SOURCE_OFFLINE) {
+                       if (map_offline != null)
+                               map_offline.show(telem_state, state, from_receiver, receiver);
+               } else {
+                       if (map_online != null)
+                               map_online.show(telem_state, state, from_receiver, receiver);
+               }
        }
 
+       @Override
        public void set_map_type(int map_type) {
-               if (map != null)
-                       map.set_maptype(map_type);
+               if (map_offline != null)
+                       map_offline.set_map_type(map_type);
+               if (map_online != null)
+                       map_online.set_map_type(map_type);
+       }
+
+       @Override
+       public void set_map_source(int map_source) {
+               this.map_source = map_source;
+               if (map_source == AltosDroidPreferences.MAP_SOURCE_OFFLINE) {
+                       if (map_online != null)
+                               map_online.set_visible(false);
+                       if (map_offline != null) {
+                               map_offline.set_visible(true);
+                               map_offline.show(last_telem_state, last_state, last_from_receiver, last_receiver);
+                       }
+               } else {
+                       if (map_offline != null)
+                               map_offline.set_visible(false);
+                       if (map_online != null) {
+                               map_online.set_visible(true);
+                               map_online.show(last_telem_state, last_state, last_from_receiver, last_receiver);
+                       }
+               }
        }
 
        public TabMapOffline() {