Switch from GPLv2 to GPLv2+
[fw/altos] / altosdroid / src / org / altusmetrum / AltosDroid / PreloadMapActivity.java
index 2febaf29e5ccdc5c2b42e6cfd05f2fb3908261f5..a8e87bf265773e64c448af238feef8ff26dfcd40 100644 (file)
@@ -3,7 +3,8 @@
  *
  * 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.
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -36,8 +37,12 @@ import android.view.Window;
 import android.view.View.OnClickListener;
 import android.widget.*;
 import android.widget.AdapterView.*;
+import android.location.Location;
+import android.location.LocationManager;
+import android.location.LocationListener;
+import android.location.Criteria;
 
-import org.altusmetrum.altoslib_7.*;
+import org.altusmetrum.altoslib_11.*;
 
 /**
  * This Activity appears as a dialog. It lists any paired devices and
@@ -45,7 +50,7 @@ import org.altusmetrum.altoslib_7.*;
  * by the user, the MAC address of the device is sent back to the parent
  * Activity in the result Intent.
  */
-public class PreloadMapActivity extends Activity implements AltosLaunchSiteListener, AltosMapInterface, AltosMapLoaderListener {
+public class PreloadMapActivity extends Activity implements AltosLaunchSiteListener, AltosMapLoaderListener, LocationListener {
 
        private ArrayAdapter<AltosLaunchSite> known_sites_adapter;
 
@@ -54,18 +59,25 @@ public class PreloadMapActivity extends Activity implements AltosLaunchSiteListe
        private CheckBox        roadmap;
        private CheckBox        terrain;
 
+       private Spinner         known_sites_spinner;
        private Spinner         min_zoom;
        private Spinner         max_zoom;
-       private Spinner         tile_radius;
+       private TextView        radius_label;
+       private Spinner         radius;
 
        private EditText        latitude;
        private EditText        longitude;
 
        private ProgressBar     progress;
 
+       private AltosMapLoader  loader;
+
+       long    loader_notify_time;
+
        /* AltosMapLoaderListener interfaces */
        public void loader_start(final int max) {
-               AltosDebug.debug("loader_start max %d\n", max);
+               loader_notify_time = System.currentTimeMillis();
+
                this.runOnUiThread(new Runnable() {
                                public void run() {
                                        progress.setMax(max);
@@ -75,7 +87,13 @@ public class PreloadMapActivity extends Activity implements AltosLaunchSiteListe
        }
 
        public void loader_notify(final int cur, final int max, final String name) {
-               AltosDebug.debug("loader_notify cur %4d max %4d %s\n", cur, max, name);
+               long    now = System.currentTimeMillis();
+
+               if (now - loader_notify_time < 100)
+                       return;
+
+               loader_notify_time = now;
+
                this.runOnUiThread(new Runnable() {
                                public void run() {
                                        progress.setProgress(cur);
@@ -84,7 +102,7 @@ public class PreloadMapActivity extends Activity implements AltosLaunchSiteListe
        }
 
        public void loader_done(int max) {
-               AltosDebug.debug("loader_done max %d\n", max);
+               loader = null;
                this.runOnUiThread(new Runnable() {
                                public void run() {
                                        progress.setProgress(0);
@@ -93,7 +111,12 @@ public class PreloadMapActivity extends Activity implements AltosLaunchSiteListe
                        });
        }
 
+       public void debug(String format, Object ... arguments) {
+               AltosDebug.debug(format, arguments);
+       }
+
        /* AltosLaunchSiteListener interface */
+
        public void notify_launch_sites(final List<AltosLaunchSite> sites) {
                this.runOnUiThread(new Runnable() {
                                public void run() {
@@ -103,64 +126,37 @@ public class PreloadMapActivity extends Activity implements AltosLaunchSiteListe
                        });
        }
 
-       AltosMap        map;
-       AltosMapLoader  loader;
-
-       class PreloadMapImage implements AltosImage {
-               public void flush() {
-               }
-
-               public PreloadMapImage(File file) {
-                       AltosDebug.debug("preload file %s\n", file.toString());
-               }
-       }
-
-       public AltosMapPath new_path() {
-               return null;
-       }
+       /* LocationProvider interface */
 
-       public AltosMapLine new_line() {
-               return null;
-       }
+       AltosLaunchSite current_location_site;
 
-       public AltosImage load_image(File file) throws Exception {
-               return new PreloadMapImage(file);
-       }
+       public void onLocationChanged(Location location) {
+               AltosDebug.debug("location changed");
+               if (current_location_site == null) {
+                       AltosLaunchSite selected_item = (AltosLaunchSite) known_sites_spinner.getSelectedItem();
 
-       public AltosMapMark new_mark(double lat, double lon, int state) {
-               return null;
-       }
-
-       class PreloadMapTile extends AltosMapTile {
-               public void paint(AltosMapTransform t) {
-               }
+                       current_location_site = new AltosLaunchSite("Current Location", location.getLatitude(), location.getLongitude());
+                       known_sites_adapter.insert(current_location_site, 0);
 
-               public PreloadMapTile(AltosMapTileListener listener, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
-                       super(listener, upper_left, center, zoom, maptype, px_size, 2);
+                       if (selected_item != null)
+                               known_sites_spinner.setSelection(known_sites_adapter.getPosition(selected_item));
+                       else {
+                               latitude.setText(new StringBuffer(String.format("%12.6f", current_location_site.latitude)));
+                               longitude.setText(new StringBuffer(String.format("%12.6f", current_location_site.longitude)));
+                       }
+               } else {
+                       current_location_site.latitude = location.getLatitude();
+                       current_location_site.longitude = location.getLongitude();
                }
-
-       }
-
-       public AltosMapTile new_tile(AltosMapTileListener listener, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
-               return new PreloadMapTile(listener, upper_left, center, zoom, maptype, px_size);
        }
 
-       public int width() {
-               return AltosMap.px_size;
+       public void onStatusChanged(String provider, int status, Bundle extras) {
        }
 
-       public int height() {
-               return AltosMap.px_size;
+       public void onProviderEnabled(String provider) {
        }
 
-       public void repaint() {
-       }
-
-       public void repaint(AltosRectangle damage) {
-       }
-
-       public void set_zoom_label(String label) {
-               AltosDebug.debug("zoom label %s\n", label);
+       public void onProviderDisabled(String provider) {
        }
 
        private double text(EditText view) throws ParseException {
@@ -187,8 +183,17 @@ public class PreloadMapActivity extends Activity implements AltosLaunchSiteListe
                return value(max_zoom);
        }
 
-       private int radius() {
-               return value(tile_radius);
+       private double value_distance(Spinner spinner) {
+               return (Double) spinner.getSelectedItem();
+       }
+
+       private double radius() {
+               double r = value_distance(radius);
+               if (AltosPreferences.imperial_units())
+                       r = AltosConvert.miles_to_meters(r);
+               else
+                       r = r * 1000;
+               return r;
        }
 
        private int bit(CheckBox box, int value) {
@@ -205,18 +210,22 @@ public class PreloadMapActivity extends Activity implements AltosLaunchSiteListe
        }
 
        private void load() {
+               if (loader != null)
+                       return;
+
                try {
                        double  lat = latitude();
                        double  lon = longitude();
                        int     min = min_z();
                        int     max = max_z();
-                       int     r = radius();
+                       double  r = radius();
                        int     t = types();
 
-                       AltosDebug.debug("load lat %12.6f lon %12.6f min %d max %d r %d types %x\n",
+                       AltosDebug.debug("PreloadMap load %f %f %d %d %f %d\n",
                                         lat, lon, min, max, r, t);
-                       loader.load(lat, lon, min, max, r, t);
+                       loader = new AltosMapLoader(this, lat, lon, min, max, r, t, AltosMapOffline.scale);
                } catch (ParseException e) {
+                       AltosDebug.debug("PreloadMap load raised exception %s", e.toString());
                }
        }
 
@@ -238,11 +247,40 @@ public class PreloadMapActivity extends Activity implements AltosLaunchSiteListe
                spinner.setSelection(spinner_def);
        }
 
+
+       private void add_distance(Spinner spinner, double[] distances_km, double def_km, double[] distances_mi, double def_mi) {
+
+               ArrayAdapter<Double> adapter = new ArrayAdapter<Double>(this, android.R.layout.simple_spinner_item);
+
+               int     spinner_def = 0;
+               int     pos = 0;
+
+               double[] distances;
+               double  def;
+               if (AltosPreferences.imperial_units()) {
+                       distances = distances_mi;
+                       def = def_mi;
+               } else {
+                       distances = distances_km;
+                       def = def_km;
+               }
+
+               for (int i = 0; i < distances.length; i++) {
+                       adapter.add(distances[i]);
+                       if (distances[i] == def)
+                               spinner_def = pos;
+                       pos++;
+               }
+
+               spinner.setAdapter(adapter);
+               spinner.setSelection(spinner_def);
+       }
+
+
+
        class SiteListListener implements OnItemSelectedListener {
                public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
                        AltosLaunchSite site = (AltosLaunchSite) parent.getItemAtPosition(pos);
-                       AltosDebug.debug("Site selected: %s\n", site.toString());
-
                        latitude.setText(new StringBuffer(String.format("%12.6f", site.latitude)));
                        longitude.setText(new StringBuffer(String.format("%12.6f", site.longitude)));
                }
@@ -253,12 +291,15 @@ public class PreloadMapActivity extends Activity implements AltosLaunchSiteListe
                }
        }
 
+       double[]        radius_mi = { 1, 2, 5, 10, 20 };
+       double          radius_def_mi = 2;
+       double[]        radius_km = { 1, 2, 5, 10, 20, 30 };
+       double          radius_def_km = 2;
+
        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
 
-               AltosDebug.debug("preload map onCreate");
-
                // Setup the window
                requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
                setContentView(R.layout.map_preload);
@@ -292,14 +333,19 @@ public class PreloadMapActivity extends Activity implements AltosLaunchSiteListe
                add_numbers(max_zoom,
                            AltosMap.min_zoom - AltosMap.default_zoom,
                            AltosMap.max_zoom - AltosMap.default_zoom, 2);
-               tile_radius = (Spinner) findViewById(R.id.preload_tile_radius);
-               add_numbers(tile_radius, 1, 5, 3);
+               radius_label = (TextView) findViewById(R.id.preload_radius_label);
+               radius = (Spinner) findViewById(R.id.preload_radius);
+               if (AltosPreferences.imperial_units())
+                       radius_label.setText("Radius (miles)");
+               else
+                       radius_label.setText("Radius (km)");
+               add_distance(radius, radius_km, radius_def_km, radius_mi, radius_def_mi);
 
                progress = (ProgressBar) findViewById(R.id.preload_progress);
 
                // Initialize array adapters. One for already paired devices and
                // one for newly discovered devices
-               Spinner known_sites_spinner = (Spinner) findViewById(R.id.preload_site_list);
+               known_sites_spinner = (Spinner) findViewById(R.id.preload_site_list);
 
                known_sites_adapter = new ArrayAdapter<AltosLaunchSite>(this, android.R.layout.simple_spinner_item);
 
@@ -308,9 +354,10 @@ public class PreloadMapActivity extends Activity implements AltosLaunchSiteListe
                known_sites_spinner.setAdapter(known_sites_adapter);
                known_sites_spinner.setOnItemSelectedListener(new SiteListListener());
 
-               map = new AltosMap(this);
+               // Listen for GPS and Network position updates
+               LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
 
-               loader = new AltosMapLoader(map, this);
+               locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, this);
 
                new AltosLaunchSites(this);
        }
@@ -318,5 +365,11 @@ public class PreloadMapActivity extends Activity implements AltosLaunchSiteListe
        @Override
        protected void onDestroy() {
                super.onDestroy();
+
+               if (loader != null)
+                       loader.abort();
+
+               // Stop listening for location updates
+               ((LocationManager) getSystemService(Context.LOCATION_SERVICE)).removeUpdates(this);
        }
 }