diff options
| author | Keith Packard <keithp@keithp.com> | 2015-05-28 01:05:18 -0700 |
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2015-05-28 01:07:25 -0700 |
| commit | 85013045ca505096064aaf45c312b158d0263d2a (patch) | |
| tree | 7ac9da1e5a8ceca582c91fe14add93df3ff56659 /altosdroid/src | |
| parent | ba698c2cc48677735046d0881df9c180674e4082 (diff) | |
altosdroid: Add map types and map preloading UIs
This adds an ugly dialog to select which maps to preload, and also
adds the ability to display other map types.
Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'altosdroid/src')
7 files changed, 455 insertions, 3 deletions
diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java index 65618646..97373ab8 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java @@ -73,6 +73,8 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener { // Intent request codes public static final int REQUEST_CONNECT_DEVICE = 1; public static final int REQUEST_ENABLE_BT = 2; + public static final int REQUEST_PRELOAD_MAPS = 3; + public static final int REQUEST_MAP_TYPE = 4; public static FragmentManager fm; @@ -630,6 +632,10 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener { finish(); } break; + case REQUEST_MAP_TYPE: + if (resultCode == Activity.RESULT_OK) + set_map_type(data); + break; } } @@ -669,6 +675,16 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener { } } + private void set_map_type(Intent data) { + int mode = data.getIntExtra(MapTypeActivity.EXTRA_MAP_TYPE, -1); + + AltosDebug.debug("intent set_map_type %d\n", mode); + if (mode != -1) { + for (AltosDroidTab mTab : mTabs) + mTab.set_map_type(mode); + } + } + @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); @@ -789,6 +805,14 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener { boolean imperial = AltosPreferences.imperial_units(); AltosPreferences.set_imperial_units(!imperial); return true; + case R.id.preload_maps: + serverIntent = new Intent(this, PreloadMapActivity.class); + startActivityForResult(serverIntent, REQUEST_PRELOAD_MAPS); + return true; + case R.id.map_type: + serverIntent = new Intent(this, MapTypeActivity.class); + startActivityForResult(serverIntent, REQUEST_MAP_TYPE); + return true; } return false; } diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java index d33ad05b..b3824aa3 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java @@ -37,6 +37,9 @@ public abstract class AltosDroidTab extends Fragment implements AltosUnitsListen public abstract String tab_name(); + public void set_map_type(int map_type) { + } + public void units_changed(boolean imperial_units) { if (!isHidden() && last_state != null) show(last_state, last_from_receiver, last_receiver); diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/MapTypeActivity.java b/altosdroid/src/org/altusmetrum/AltosDroid/MapTypeActivity.java new file mode 100644 index 00000000..e43841a8 --- /dev/null +++ b/altosdroid/src/org/altusmetrum/AltosDroid/MapTypeActivity.java @@ -0,0 +1,84 @@ +/* + * Copyright © 2015 Keith Packard <keithp@keithp.com> + * + * 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.AltosDroid; + +import java.util.*; +import org.altusmetrum.AltosDroid.R; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Bundle; +import android.view.View; +import android.view.Window; +import android.view.View.OnClickListener; +import android.widget.*; +import android.widget.AdapterView.*; + +import org.altusmetrum.altoslib_7.*; + +public class MapTypeActivity extends Activity { + private Button hybrid; + private Button satellite; + private Button roadmap; + private Button terrain; + private int selected_type; + + public static final String EXTRA_MAP_TYPE = "map_type"; + + private void done(int type) { + + Intent intent = new Intent(); + intent.putExtra(EXTRA_MAP_TYPE, type); + setResult(Activity.RESULT_OK, intent); + finish(); + } + + public void selectType(View view) { + AltosDebug.debug("selectType %s", view.toString()); + if (view == hybrid) + done(AltosMap.maptype_hybrid); + if (view == satellite) + done(AltosMap.maptype_satellite); + if (view == roadmap) + done(AltosMap.maptype_roadmap); + if (view == terrain) + done(AltosMap.maptype_terrain); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Setup the window + requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); + setContentView(R.layout.map_type); + + hybrid = (Button) findViewById(R.id.map_type_hybrid); + satellite = (Button) findViewById(R.id.map_type_satellite); + roadmap = (Button) findViewById(R.id.map_type_roadmap); + terrain = (Button) findViewById(R.id.map_type_terrain); + + // Set result CANCELED incase the user backs out + setResult(Activity.RESULT_CANCELED); + } +} diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/PreloadMapActivity.java b/altosdroid/src/org/altusmetrum/AltosDroid/PreloadMapActivity.java new file mode 100644 index 00000000..2febaf29 --- /dev/null +++ b/altosdroid/src/org/altusmetrum/AltosDroid/PreloadMapActivity.java @@ -0,0 +1,322 @@ +/* + * Copyright © 2015 Keith Packard <keithp@keithp.com> + * + * 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.AltosDroid; + +import java.util.*; +import java.io.*; +import java.text.*; + +import org.altusmetrum.AltosDroid.R; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Bundle; +import android.view.View; +import android.view.Window; +import android.view.View.OnClickListener; +import android.widget.*; +import android.widget.AdapterView.*; + +import org.altusmetrum.altoslib_7.*; + +/** + * This Activity appears as a dialog. It lists any paired devices and + * devices detected in the area after discovery. When a device is chosen + * 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 { + + private ArrayAdapter<AltosLaunchSite> known_sites_adapter; + + private CheckBox hybrid; + private CheckBox satellite; + private CheckBox roadmap; + private CheckBox terrain; + + private Spinner min_zoom; + private Spinner max_zoom; + private Spinner tile_radius; + + private EditText latitude; + private EditText longitude; + + private ProgressBar progress; + + /* AltosMapLoaderListener interfaces */ + public void loader_start(final int max) { + AltosDebug.debug("loader_start max %d\n", max); + this.runOnUiThread(new Runnable() { + public void run() { + progress.setMax(max); + progress.setProgress(0); + } + }); + } + + 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); + this.runOnUiThread(new Runnable() { + public void run() { + progress.setProgress(cur); + } + }); + } + + public void loader_done(int max) { + AltosDebug.debug("loader_done max %d\n", max); + this.runOnUiThread(new Runnable() { + public void run() { + progress.setProgress(0); + finish(); + } + }); + } + + /* AltosLaunchSiteListener interface */ + public void notify_launch_sites(final List<AltosLaunchSite> sites) { + this.runOnUiThread(new Runnable() { + public void run() { + for (AltosLaunchSite site : sites) + known_sites_adapter.add(site); + } + }); + } + + 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; + } + + public AltosMapLine new_line() { + return null; + } + + public AltosImage load_image(File file) throws Exception { + return new PreloadMapImage(file); + } + + public AltosMapMark new_mark(double lat, double lon, int state) { + return null; + } + + class PreloadMapTile extends AltosMapTile { + public void paint(AltosMapTransform t) { + } + + 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); + } + + } + + 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 int height() { + return AltosMap.px_size; + } + + public void repaint() { + } + + public void repaint(AltosRectangle damage) { + } + + public void set_zoom_label(String label) { + AltosDebug.debug("zoom label %s\n", label); + } + + private double text(EditText view) throws ParseException { + return AltosParse.parse_double_locale(view.getEditableText().toString()); + } + + private double latitude() throws ParseException { + return text(latitude); + } + + private double longitude() throws ParseException { + return text(longitude); + } + + private int value(Spinner spinner) { + return (Integer) spinner.getSelectedItem(); + } + + private int min_z() { + return value(min_zoom); + } + + private int max_z() { + return value(max_zoom); + } + + private int radius() { + return value(tile_radius); + } + + private int bit(CheckBox box, int value) { + if (box.isChecked()) + return 1 << value; + return 0; + } + + private int types() { + return (bit(hybrid, AltosMap.maptype_hybrid) | + bit(satellite, AltosMap.maptype_satellite) | + bit(roadmap, AltosMap.maptype_roadmap) | + bit(terrain, AltosMap.maptype_terrain)); + } + + private void load() { + try { + double lat = latitude(); + double lon = longitude(); + int min = min_z(); + int max = max_z(); + int r = radius(); + int t = types(); + + AltosDebug.debug("load lat %12.6f lon %12.6f min %d max %d r %d types %x\n", + lat, lon, min, max, r, t); + loader.load(lat, lon, min, max, r, t); + } catch (ParseException e) { + } + } + + private void add_numbers(Spinner spinner, int min, int max, int def) { + + ArrayAdapter<Integer> adapter = new ArrayAdapter<Integer>(this, android.R.layout.simple_spinner_item); + + int spinner_def = 0; + int pos = 0; + + for (int i = min; i <= max; i++) { + adapter.add(new Integer(i)); + if (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))); + } + public void onNothingSelected(AdapterView<?> parent) { + } + + public SiteListListener() { + } + } + + @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); + + // Set result CANCELED incase the user backs out + setResult(Activity.RESULT_CANCELED); + + // Initialize the button to perform device discovery + Button loadButton = (Button) findViewById(R.id.preload_load); + loadButton.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + load(); + } + }); + + latitude = (EditText) findViewById(R.id.preload_latitude); + longitude = (EditText) findViewById(R.id.preload_longitude); + + hybrid = (CheckBox) findViewById(R.id.preload_hybrid); + satellite = (CheckBox) findViewById(R.id.preload_satellite); + roadmap = (CheckBox) findViewById(R.id.preload_roadmap); + terrain = (CheckBox) findViewById(R.id.preload_terrain); + + hybrid.setChecked(true); + + min_zoom = (Spinner) findViewById(R.id.preload_min_zoom); + add_numbers(min_zoom, + AltosMap.min_zoom - AltosMap.default_zoom, + AltosMap.max_zoom - AltosMap.default_zoom, -2); + max_zoom = (Spinner) findViewById(R.id.preload_max_zoom); + 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); + + 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_adapter = new ArrayAdapter<AltosLaunchSite>(this, android.R.layout.simple_spinner_item); + + known_sites_adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + + known_sites_spinner.setAdapter(known_sites_adapter); + known_sites_spinner.setOnItemSelectedListener(new SiteListListener()); + + map = new AltosMap(this); + + loader = new AltosMapLoader(map, this); + + new AltosLaunchSites(this); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + } +} diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java index 83c8f7f8..5376d423 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java @@ -199,6 +199,19 @@ public class TabMap extends AltosDroidTab { } + public void set_map_type(int map_type) { + if (mMap != null) { + if (map_type == AltosMap.maptype_hybrid) + mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID); + else if (map_type == AltosMap.maptype_satellite) + mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE); + else if (map_type == AltosMap.maptype_terrain) + mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN); + else + mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); + } + } + public TabMap() { } } diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabMapOffline.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabMapOffline.java index 6742e606..31acda75 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TabMapOffline.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabMapOffline.java @@ -39,6 +39,7 @@ public class TabMapOffline extends AltosDroidTab implements AltosMapInterface { AltosMap map; AltosLatLon here; + AltosLatLon pad; Canvas canvas; Paint paint; @@ -84,6 +85,7 @@ public class TabMapOffline extends AltosDroidTab implements AltosMapInterface { 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); } @@ -271,8 +273,6 @@ public class TabMapOffline extends AltosDroidTab implements AltosMapInterface { class MapMark extends AltosMapMark { public void paint(AltosMapTransform t) { - if (state == AltosLib.ao_flight_boost) - draw_bitmap(lat_lon, pad_bitmap, pad_off_x, pad_off_y); } MapMark(double lat, double lon, int state) { @@ -472,6 +472,8 @@ public class TabMapOffline extends AltosDroidTab implements AltosMapInterface { 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) { @@ -489,6 +491,11 @@ public class TabMapOffline extends AltosDroidTab implements AltosMapInterface { } + public void set_map_type(int map_type) { + if (map != null) + map.set_maptype(map_type); + } + public TabMapOffline() { } } diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java index 627f5957..eae360db 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java @@ -334,7 +334,6 @@ public class TelemetryService extends Service implements LocationListener { private void start_altos_bluetooth(DeviceAddress address, boolean pause) { // Get the BLuetoothDevice object - AltosDebug.check_ui("start_altos_bluetooth\n"); BluetoothDevice device = bluetooth_adapter.getRemoteDevice(address.address); disconnect(false); |
