android:prompt="@string/preload_max_zoom"
android:spinnerMode="dropdown"
/>
- <TextView android:id="@+id/preload_tile_radius_label"
+ <TextView android:id="@+id/preload_radius_label"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:text="@string/preload_tile_radius"
+ android:text="@string/preload_radius"
/>
- <Spinner android:id="@+id/preload_tile_radius"
+ <Spinner android:id="@+id/preload_radius"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:prompt="@string/preload_tile_radius"
+ android:prompt="@string/preload_radius"
android:spinnerMode="dropdown"
/>
<Button android:id="@+id/preload_load"
<string name="preload_terrain">Terrain</string>
<string name="preload_min_zoom">Minimum Zoom</string>
<string name="preload_max_zoom">Maximum Zoom</string>
- <string name="preload_tile_radius">Tile Radius</string>
+ <string name="preload_radius">Radius</string>
<string name="preload_load">Load Map</string>
</resources>
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;
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.distance.inverse(r);
+ else
+ r = r * 1000;
+ return r;
}
private int bit(CheckBox box, int value) {
double lon = longitude();
int min = min_z();
int max = max_z();
- int r = radius();
+ double r = radius();
int t = types();
+ 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);
} catch (ParseException e) {
+ AltosDebug.debug("PreloadMap load raised exception %s", e.toString());
}
}
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);
}
}
+ 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);
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, 5);
+ 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);
import java.net.URL;
import java.net.URLConnection;
-public class AltosMapLoader implements AltosMapTileListener {
+public class AltosMapLoader implements AltosMapTileListener, AltosMapStoreListener {
AltosMapLoaderListener listener;
double latitude, longitude;
int cur_z;
int all_types;
int cur_type;
- int radius;
+ double radius;
- int tiles_per_layer;
- int tiles_loaded;
+ int tiles_loaded_layer;
+ int tiles_loaded_total;
+ int tiles_this_layer;
+ int tiles_total;
int layers_total;
int layers_loaded;
AltosMap map;
+ int tile_radius(int zoom) {
+ double delta_lon = AltosMapTransform.lon_from_distance(latitude, radius);
+
+ AltosMapTransform t = new AltosMapTransform(256, 256, zoom + AltosMap.default_zoom, new AltosLatLon(latitude, longitude));
+
+ AltosPointDouble center = t.point(new AltosLatLon(latitude, longitude));
+ AltosPointDouble edge = t.point(new AltosLatLon(latitude, longitude + delta_lon));
+
+ int tile_radius = (int) Math.ceil(Math.abs(center.x - edge.x) / AltosMap.px_size);
+
+ return tile_radius;
+ }
+
+ int tiles_per_layer(int zoom) {
+ int tile_radius = tile_radius(zoom);
+ return (tile_radius * 2 + 1) * (tile_radius * 2 + 1);
+ }
+
public void do_load() {
- map.set_load_params(cur_z + AltosMap.default_zoom, cur_type, latitude, longitude, radius, this);
+ tiles_this_layer = tiles_per_layer(cur_z);
+ tiles_loaded_layer = 0;
+ listener.debug("tiles_this_layer %d (zoom %d)\n", tiles_this_layer, cur_z);
+
+ int load_radius = tile_radius(cur_z);
+ int zoom = cur_z + AltosMap.default_zoom;
+ int maptype = cur_type;
+ AltosLatLon load_centre = new AltosLatLon(latitude, longitude);
+ AltosMapTransform transform = new AltosMapTransform(256, 256, zoom, load_centre);
+
+ map.centre(load_centre);
+
+ AltosPointInt upper_left;
+ AltosPointInt lower_right;
+
+ AltosPointInt centre = AltosMap.floor(transform.point(load_centre));
+
+ upper_left = new AltosPointInt(centre.x - load_radius * AltosMap.px_size,
+ centre.y - load_radius * AltosMap.px_size);
+ lower_right = new AltosPointInt(centre.x + load_radius * AltosMap.px_size,
+ centre.y + load_radius * AltosMap.px_size);
+
+
+ for (int y = (int) upper_left.y; y <= lower_right.y; y += AltosMap.px_size) {
+ for (int x = (int) upper_left.x; x <= lower_right.x; x += AltosMap.px_size) {
+ listener.debug("Make tile at %d, %d\n", x, y);
+ AltosPointInt point = new AltosPointInt(x, y);
+ AltosLatLon ul = transform.lat_lon(point);
+ AltosLatLon center = transform.lat_lon(new AltosPointDouble(x + AltosMap.px_size/2, y + AltosMap.px_size/2));
+ AltosMapTile tile = map.map_interface.new_tile(this, ul, center, zoom, maptype, AltosMap.px_size);
+ tile.add_store_listener(this);
+ if (tile.store_status() != AltosMapTile.loading)
+ notify_tile(tile, tile.store_status());
+ }
+ }
}
public int next_type(int start) {
}
cur_type = next_type(0);
- tiles_per_layer = (radius * 2 + 1) * (radius * 2 + 1);
+
+ for (int z = min_z; z <= max_z; z++)
+ tiles_total += tiles_per_layer(z);
+
layers_total = (max_z - min_z + 1) * ntype;
layers_loaded = 0;
- tiles_loaded = 0;
+ tiles_loaded_total = 0;
+
+ listener.debug("total tiles %d\n", tiles_total);
- listener.loader_start(layers_total * tiles_per_layer);
+ listener.loader_start(tiles_total);
do_load();
}
- public void load(double latitude, double longitude, int min_z, int max_z, int radius, int all_types) {
+ public void load(double latitude, double longitude, int min_z, int max_z, double radius, int all_types) {
+ listener.debug("lat %f lon %f min_z %d max_z %d radius %f all_types %d\n",
+ latitude, longitude, min_z, max_z, radius, all_types);
this.latitude = latitude;
this.longitude = longitude;
this.min_z = min_z;
start_load();
}
- public synchronized void notify_tile(AltosMapTile tile, int status) {
+ public synchronized void notify_store(AltosMapStore store, int status) {
boolean do_next = false;
if (status == AltosMapTile.loading)
return;
if (layers_loaded >= layers_total)
return;
- ++tiles_loaded;
+ ++tiles_loaded_total;
+ ++tiles_loaded_layer;
+ listener.debug("total %d layer %d\n", tiles_loaded_total, tiles_loaded_layer);
- if (tiles_loaded == tiles_per_layer) {
- tiles_loaded = 0;
+ if (tiles_loaded_layer == tiles_this_layer) {
++layers_loaded;
+ listener.debug("%d layers loaded\n", layers_loaded);
if (layers_loaded == layers_total) {
- listener.loader_done(layers_total * tiles_per_layer);
+ listener.loader_done(tiles_total);
return;
} else {
do_next = true;
}
}
- listener.loader_notify(layers_loaded * tiles_per_layer + tiles_loaded,
- layers_total * tiles_per_layer, tile.store.file.toString());
+ listener.loader_notify(tiles_loaded_total,
+ tiles_total, store.file.toString());
if (do_next)
next_load();
}
+ public synchronized void notify_tile(AltosMapTile tile, int status) {
+ notify_store(tile.store, status);
+ }
+
public AltosMapCache cache() { return map.cache(); }
public AltosMapLoader(AltosMap map, AltosMapLoaderListener listener) {
public abstract void loader_notify(int cur, int max, String name);
public abstract void loader_done(int max);
+
+ public abstract void debug(String format, Object ... arguments);
}
JComboBox<Integer> min_zoom;
JComboBox<Integer> max_zoom;
- JComboBox<Integer> radius;
+ JComboBox<Double> radius;
Integer[] zooms = { -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6 };
- Integer[] radii = { 1, 2, 3, 4, 5 };
+
+ Double[] radius_mi = { 1.0, 2.0, 5.0, 10.0, 20.0 };
+ Double radius_def_mi = 5.0;
+ Double[] radius_km = { 2.0, 5.0, 10.0, 20.0, 30.0 };
+ Double radius_def_km = 10.0;
+
static final String[] lat_hemi_names = { "N", "S" };
static final String[] lon_hemi_names = { "E", "W" };
});
}
+ public void debug(String format, Object ... arguments) {
+ System.out.printf(format, arguments);
+ }
+
+
private int all_types() {
int all_types = 0;
for (int t = AltosMap.maptype_hybrid; t <= AltosMap.maptype_terrain; t++)
int max_z = (Integer) max_zoom.getSelectedItem();
if (max_z < min_z)
max_z = min_z;
- int r = (Integer) radius.getSelectedItem();
+ Double r = (Double) radius.getSelectedItem();
+
+ if (AltosPreferences.imperial_units())
+ r = AltosConvert.distance.inverse(r);
+ else
+ r = r * 1000;
loading = true;
loader.load(latitude, longitude, min_z, max_z, r, all_types());
c.gridy = 3;
pane.add(max_zoom, c);
- JLabel radius_label = new JLabel("Tile Radius");
+ JLabel radius_label = new JLabel(String.format("Map Radius (%s)",
+ AltosPreferences.imperial_units() ? "miles" : "km"));
c.gridx = 4;
c.gridy = 4;
pane.add(radius_label, c);
- radius = new JComboBox<Integer>(radii);
- radius.setSelectedItem(radii[4]);
+ Double[] radii;
+ Double radius_default;
+
+ if (AltosPreferences.imperial_units())
+ radii = radius_mi;
+ else
+ radii = radius_km;
+ radius = new JComboBox<Double>(radii);
+ radius.setSelectedItem(radii[2]);
radius.setEditable(true);
c.gridx = 5;
c.gridy = 4;