diff options
| author | Bdale Garbee <bdale@gag.com> | 2015-07-16 13:36:59 -0600 | 
|---|---|---|
| committer | Bdale Garbee <bdale@gag.com> | 2015-07-16 13:36:59 -0600 | 
| commit | f4f0f044df1251d64d44bf62d25b488fd04a05c8 (patch) | |
| tree | 12efee1447a67d8cf37b6f447c011708264b8266 /altoslib | |
| parent | b25690062ac04a588ad4d11740597c20e516eb1a (diff) | |
| parent | 570daace9caf7647a09c53d5c75593cc4c98b93b (diff) | |
Merge branch 'branch-1.6' into debian
Diffstat (limited to 'altoslib')
131 files changed, 2589 insertions, 124 deletions
diff --git a/altoslib/.gitignore b/altoslib/.gitignore index ff0fd710..dc8b7e5e 100644 --- a/altoslib/.gitignore +++ b/altoslib/.gitignore @@ -1,3 +1,4 @@  bin  classaltoslib.stamp  altoslib*.jar +AltosVersion.java diff --git a/altoslib/AltosAccel.java b/altoslib/AltosAccel.java index b11dc3a1..e4e7df90 100644 --- a/altoslib/AltosAccel.java +++ b/altoslib/AltosAccel.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*; diff --git a/altoslib/AltosCRCException.java b/altoslib/AltosCRCException.java index 4167aecf..eaff0808 100644 --- a/altoslib/AltosCRCException.java +++ b/altoslib/AltosCRCException.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public class AltosCRCException extends Exception {  	public int rssi; diff --git a/altoslib/AltosCSV.java b/altoslib/AltosCSV.java index 02f7806f..edb23e69 100644 --- a/altoslib/AltosCSV.java +++ b/altoslib/AltosCSV.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*;  import java.util.*; diff --git a/altoslib/AltosCompanion.java b/altoslib/AltosCompanion.java index 8992b018..86b23eb6 100644 --- a/altoslib/AltosCompanion.java +++ b/altoslib/AltosCompanion.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*; diff --git a/altoslib/AltosConfigData.java b/altoslib/AltosConfigData.java index d8f4d945..8e052934 100644 --- a/altoslib/AltosConfigData.java +++ b/altoslib/AltosConfigData.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.util.*;  import java.text.*; @@ -75,6 +75,7 @@ public class AltosConfigData implements Iterable<String> {  	/* HAS_APRS */  	public int		aprs_interval;  	public int		aprs_ssid; +	public int		aprs_format;  	/* HAS_BEEP */  	public int		beep; @@ -270,6 +271,7 @@ public class AltosConfigData implements Iterable<String> {  		aprs_interval = -1;  		aprs_ssid = -1; +		aprs_format = -1;  		beep = -1; @@ -370,6 +372,7 @@ public class AltosConfigData implements Iterable<String> {  		/* HAS_APRS */  		try { aprs_interval = get_int(line, "APRS interval:"); } catch (Exception e) {}  		try { aprs_ssid = get_int(line, "APRS SSID:"); } catch (Exception e) {} +		try { aprs_format = get_int(line, "APRS format:"); } catch (Exception e) {}  		/* HAS_BEEP */  		try { beep = get_int(line, "Beeper setting:"); } catch (Exception e) {} @@ -518,6 +521,8 @@ public class AltosConfigData implements Iterable<String> {  			aprs_interval = source.aprs_interval();  		if (aprs_ssid >= 0)  			aprs_ssid = source.aprs_ssid(); +		if (aprs_format >= 0) +			aprs_format = source.aprs_format();  		/* HAS_BEEP */  		if (beep >= 0) @@ -572,6 +577,7 @@ public class AltosConfigData implements Iterable<String> {  		dest.set_pyro_firing_time(pyro_firing_time);  		dest.set_aprs_interval(aprs_interval);  		dest.set_aprs_ssid(aprs_ssid); +		dest.set_aprs_format(aprs_format);  		dest.set_beep(beep);  		dest.set_tracker_motion(tracker_motion);  		dest.set_tracker_interval(tracker_interval); @@ -674,6 +680,8 @@ public class AltosConfigData implements Iterable<String> {  			link.printf("c A %d\n", aprs_interval);  		if (aprs_ssid >= 0)  			link.printf("c S %d\n", aprs_ssid); +		if (aprs_format >= 0) +			link.printf("c C %d\n", aprs_format);  		/* HAS_BEEP */  		if (beep >= 0) diff --git a/altoslib/AltosConfigDataException.java b/altoslib/AltosConfigDataException.java index 11aa4d24..da11336d 100644 --- a/altoslib/AltosConfigDataException.java +++ b/altoslib/AltosConfigDataException.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public class AltosConfigDataException extends Exception { diff --git a/altoslib/AltosConfigValues.java b/altoslib/AltosConfigValues.java index cfe9fc8b..f8a2fb14 100644 --- a/altoslib/AltosConfigValues.java +++ b/altoslib/AltosConfigValues.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public interface AltosConfigValues {  	/* set and get all of the dialog values */ @@ -91,6 +91,10 @@ public interface AltosConfigValues {  	public abstract void set_aprs_ssid(int new_aprs_ssid); +	public abstract int aprs_format() throws AltosConfigDataException; + +	public abstract void set_aprs_format(int new_aprs_format); +  	public abstract int beep() throws AltosConfigDataException;  	public abstract void set_beep(int new_beep); diff --git a/altoslib/AltosConvert.java b/altoslib/AltosConvert.java index a5eb7ff8..fd2f5750 100644 --- a/altoslib/AltosConvert.java +++ b/altoslib/AltosConvert.java @@ -18,7 +18,7 @@  /*   * Sensor data conversion functions   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public class AltosConvert {  	/* @@ -230,6 +230,12 @@ public class AltosConvert {  		return sensor / 32767.0 * supply * (5.6 + 10.0) / 10.0;  	} +	static double tele_bt_3_battery(int raw) { +		if (raw == AltosLib.MISSING) +			return AltosLib.MISSING; +		return 3.3 * mega_adc(raw) * (5.1 + 10.0) / 10.0; +	} +  	static double easy_mini_voltage(int sensor, int serial) {  		double	supply = 3.3;  		double	diode_offset = 0.0; diff --git a/altoslib/AltosDebug.java b/altoslib/AltosDebug.java index ef5edc6a..16dcf6f5 100644 --- a/altoslib/AltosDebug.java +++ b/altoslib/AltosDebug.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*; diff --git a/altoslib/AltosDistance.java b/altoslib/AltosDistance.java index b0666f33..a05fb7e2 100644 --- a/altoslib/AltosDistance.java +++ b/altoslib/AltosDistance.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public class AltosDistance extends AltosUnits { diff --git a/altoslib/AltosEeprom.java b/altoslib/AltosEeprom.java index 777988e7..194b10e8 100644 --- a/altoslib/AltosEeprom.java +++ b/altoslib/AltosEeprom.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*;  import java.util.*; diff --git a/altoslib/AltosEepromChunk.java b/altoslib/AltosEepromChunk.java index 19a8807d..9174c6a9 100644 --- a/altoslib/AltosEepromChunk.java +++ b/altoslib/AltosEepromChunk.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.text.*;  import java.util.concurrent.*; diff --git a/altoslib/AltosEepromDownload.java b/altoslib/AltosEepromDownload.java index 9598bd93..baaeb993 100644 --- a/altoslib/AltosEepromDownload.java +++ b/altoslib/AltosEepromDownload.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*;  import java.util.*; diff --git a/altoslib/AltosEepromFile.java b/altoslib/AltosEepromFile.java index c8443549..33d4f63b 100644 --- a/altoslib/AltosEepromFile.java +++ b/altoslib/AltosEepromFile.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*;  import java.util.*; diff --git a/altoslib/AltosEepromGPS.java b/altoslib/AltosEepromGPS.java index 96cfc0e1..aeb61661 100644 --- a/altoslib/AltosEepromGPS.java +++ b/altoslib/AltosEepromGPS.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*;  import java.util.*; diff --git a/altoslib/AltosEepromHeader.java b/altoslib/AltosEepromHeader.java index fc4e9caa..95ecc32c 100644 --- a/altoslib/AltosEepromHeader.java +++ b/altoslib/AltosEepromHeader.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*;  import java.util.*; diff --git a/altoslib/AltosEepromIterable.java b/altoslib/AltosEepromIterable.java index 94487ab5..c3cd5d86 100644 --- a/altoslib/AltosEepromIterable.java +++ b/altoslib/AltosEepromIterable.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*;  import java.util.*; diff --git a/altoslib/AltosEepromList.java b/altoslib/AltosEepromList.java index 39768a21..6dc6a3d6 100644 --- a/altoslib/AltosEepromList.java +++ b/altoslib/AltosEepromList.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*;  import java.util.*; diff --git a/altoslib/AltosEepromLog.java b/altoslib/AltosEepromLog.java index 0fc82ab4..538c102b 100644 --- a/altoslib/AltosEepromLog.java +++ b/altoslib/AltosEepromLog.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.text.*;  import java.util.concurrent.*; diff --git a/altoslib/AltosEepromMega.java b/altoslib/AltosEepromMega.java index c2edcf23..d5f0e0e0 100644 --- a/altoslib/AltosEepromMega.java +++ b/altoslib/AltosEepromMega.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*;  import java.util.*; diff --git a/altoslib/AltosEepromMetrum2.java b/altoslib/AltosEepromMetrum2.java index 39425e10..1b4cb04a 100644 --- a/altoslib/AltosEepromMetrum2.java +++ b/altoslib/AltosEepromMetrum2.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*;  import java.util.*; diff --git a/altoslib/AltosEepromMini.java b/altoslib/AltosEepromMini.java index ef13d0a7..8d0343b8 100644 --- a/altoslib/AltosEepromMini.java +++ b/altoslib/AltosEepromMini.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*;  import java.util.*; diff --git a/altoslib/AltosEepromMonitor.java b/altoslib/AltosEepromMonitor.java index 35ed5a6e..1c1d1010 100644 --- a/altoslib/AltosEepromMonitor.java +++ b/altoslib/AltosEepromMonitor.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public interface AltosEepromMonitor { diff --git a/altoslib/AltosEepromTM.java b/altoslib/AltosEepromTM.java index 2bdd64f0..44b98e49 100644 --- a/altoslib/AltosEepromTM.java +++ b/altoslib/AltosEepromTM.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*;  import java.util.*; diff --git a/altoslib/AltosEepromTm.java b/altoslib/AltosEepromTm.java index 36500393..0a37a2aa 100644 --- a/altoslib/AltosEepromTm.java +++ b/altoslib/AltosEepromTm.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*;  import java.util.*; diff --git a/altoslib/AltosFile.java b/altoslib/AltosFile.java index a79216a2..cab38d6d 100644 --- a/altoslib/AltosFile.java +++ b/altoslib/AltosFile.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.File;  import java.util.*; diff --git a/altoslib/AltosFlash.java b/altoslib/AltosFlash.java index e58b652e..e4b980b0 100644 --- a/altoslib/AltosFlash.java +++ b/altoslib/AltosFlash.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*; diff --git a/altoslib/AltosFlashListener.java b/altoslib/AltosFlashListener.java index 1c7cd77d..6a7351f3 100644 --- a/altoslib/AltosFlashListener.java +++ b/altoslib/AltosFlashListener.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public interface AltosFlashListener {  	public void position(String label, int percent); diff --git a/altoslib/AltosFlightDisplay.java b/altoslib/AltosFlightDisplay.java new file mode 100644 index 00000000..33d71fc3 --- /dev/null +++ b/altoslib/AltosFlightDisplay.java @@ -0,0 +1,26 @@ +/* + * Copyright © 2010 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.altoslib_8; + +public interface AltosFlightDisplay extends AltosUnitsListener, AltosFontListener { +	void reset(); + +	void show(AltosState state, AltosListenerState listener_state); + +	String getName(); +} diff --git a/altoslib/AltosFlightReader.java b/altoslib/AltosFlightReader.java index 03c53ff4..fca0f20b 100644 --- a/altoslib/AltosFlightReader.java +++ b/altoslib/AltosFlightReader.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.text.*;  import java.io.*; diff --git a/altoslib/AltosFlightStats.java b/altoslib/AltosFlightStats.java index 82e477f8..b837ba84 100644 --- a/altoslib/AltosFlightStats.java +++ b/altoslib/AltosFlightStats.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*; diff --git a/altoslib/AltosFontListener.java b/altoslib/AltosFontListener.java new file mode 100644 index 00000000..78049350 --- /dev/null +++ b/altoslib/AltosFontListener.java @@ -0,0 +1,22 @@ +/* + * Copyright © 2011 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.altoslib_8; + +public interface AltosFontListener { +	void font_size_changed(int font_size); +} diff --git a/altoslib/AltosFrequency.java b/altoslib/AltosFrequency.java index 1dd4819d..6d2bb8d0 100644 --- a/altoslib/AltosFrequency.java +++ b/altoslib/AltosFrequency.java @@ -15,12 +15,25 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public class AltosFrequency {  	public double	frequency;  	public String	description; +	public int hashCode() { +		return new Double(frequency).hashCode(); +	} + +	public boolean equals(Object o) { +		if (o == null) +			return false; +		if (!(o instanceof AltosFrequency)) +			return false; +		AltosFrequency other = (AltosFrequency) o; +		return other.frequency == frequency; +	} +  	public String toString() {  		return String.format("%7.3f MHz %-20s",  				     frequency, description); diff --git a/altoslib/AltosGPS.java b/altoslib/AltosGPS.java index 2139efb2..a2584e77 100644 --- a/altoslib/AltosGPS.java +++ b/altoslib/AltosGPS.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.text.*;  import java.util.concurrent.*; @@ -195,10 +195,10 @@ public class AltosGPS implements Cloneable, Serializable {  			lon = AltosParse.parse_coord(words[i++]);  			alt = AltosParse.parse_int(words[i++]);  			if (version > 1 || (i < words.length && !words[i].equals("SAT"))) { -				ground_speed = AltosParse.parse_double(AltosParse.strip_suffix(words[i++], "m/s(H)")); +				ground_speed = AltosParse.parse_double_net(AltosParse.strip_suffix(words[i++], "m/s(H)"));  				course = AltosParse.parse_int(words[i++]); -				climb_rate = AltosParse.parse_double(AltosParse.strip_suffix(words[i++], "m/s(V)")); -				hdop = AltosParse.parse_double(AltosParse.strip_suffix(words[i++], "(hdop)")); +				climb_rate = AltosParse.parse_double_net(AltosParse.strip_suffix(words[i++], "m/s(V)")); +				hdop = AltosParse.parse_double_net(AltosParse.strip_suffix(words[i++], "(hdop)"));  				h_error = AltosParse.parse_int(words[i++]);  				v_error = AltosParse.parse_int(words[i++]);  			} diff --git a/altoslib/AltosGPSSat.java b/altoslib/AltosGPSSat.java index 57491f4d..44782003 100644 --- a/altoslib/AltosGPSSat.java +++ b/altoslib/AltosGPSSat.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public class AltosGPSSat {  	public int	svid; diff --git a/altoslib/AltosGreatCircle.java b/altoslib/AltosGreatCircle.java index c48755be..e13eca48 100644 --- a/altoslib/AltosGreatCircle.java +++ b/altoslib/AltosGreatCircle.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.lang.Math;  import java.io.*; @@ -28,8 +28,8 @@ public class AltosGreatCircle implements Cloneable, Serializable {  	double sqr(double a) { return a * a; } -	static final double rad = Math.PI / 180; -	static final double earth_radius = 6371.2 * 1000;	/* in meters */ +	public static final double rad = Math.PI / 180; +	public static final double earth_radius = 6371.2 * 1000;	/* in meters */  	public static final int BEARING_LONG = AltosConvert.BEARING_LONG;  	public static final int BEARING_SHORT = AltosConvert.BEARING_SHORT; diff --git a/altoslib/AltosHeight.java b/altoslib/AltosHeight.java index c4419ae6..bc20ef24 100644 --- a/altoslib/AltosHeight.java +++ b/altoslib/AltosHeight.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public class AltosHeight extends AltosUnits { diff --git a/altoslib/AltosHexfile.java b/altoslib/AltosHexfile.java index 9f45d65a..ece822d8 100644 --- a/altoslib/AltosHexfile.java +++ b/altoslib/AltosHexfile.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*;  import java.util.LinkedList; diff --git a/altoslib/AltosHexsym.java b/altoslib/AltosHexsym.java index 0c61fd02..e1561c7d 100644 --- a/altoslib/AltosHexsym.java +++ b/altoslib/AltosHexsym.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public class AltosHexsym {  	String	name; diff --git a/altoslib/AltosIMU.java b/altoslib/AltosIMU.java index 8c219d9f..7a4a705d 100644 --- a/altoslib/AltosIMU.java +++ b/altoslib/AltosIMU.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.util.concurrent.*;  import java.io.*; diff --git a/altoslib/AltosIdle.java b/altoslib/AltosIdle.java index 82b18ca2..0e2576cd 100644 --- a/altoslib/AltosIdle.java +++ b/altoslib/AltosIdle.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*;  import java.util.*; diff --git a/altoslib/AltosIdleFetch.java b/altoslib/AltosIdleFetch.java index 4c5e8285..6c0d130b 100644 --- a/altoslib/AltosIdleFetch.java +++ b/altoslib/AltosIdleFetch.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*;  import java.util.*; @@ -146,6 +146,7 @@ public class AltosIdleFetch implements AltosStateUpdate {  			state.set_callsign(config_data.callsign);  			state.set_ground_accel(config_data.accel_cal_plus);  			state.set_accel_g(config_data.accel_cal_plus, config_data.accel_cal_minus); +			state.set_product(config_data.product);  			for (AltosIdler idler : idlers) {  				if (idler.matches(config_data)) {  					idler.update_state(state, link, config_data); diff --git a/altoslib/AltosIdleMonitor.java b/altoslib/AltosIdleMonitor.java index 4d0968bf..1b62f385 100644 --- a/altoslib/AltosIdleMonitor.java +++ b/altoslib/AltosIdleMonitor.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*;  import java.util.concurrent.*; diff --git a/altoslib/AltosIdleMonitorListener.java b/altoslib/AltosIdleMonitorListener.java index fdf4be9d..1d06c4d9 100644 --- a/altoslib/AltosIdleMonitorListener.java +++ b/altoslib/AltosIdleMonitorListener.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public interface AltosIdleMonitorListener {  	public void update(AltosState state, AltosListenerState listener_state); diff --git a/altoslib/AltosIgnite.java b/altoslib/AltosIgnite.java index ffb6ed15..39f792db 100644 --- a/altoslib/AltosIgnite.java +++ b/altoslib/AltosIgnite.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.util.*;  import java.io.*; diff --git a/altoslib/AltosImage.java b/altoslib/AltosImage.java new file mode 100644 index 00000000..fc0192a3 --- /dev/null +++ b/altoslib/AltosImage.java @@ -0,0 +1,25 @@ +/* + * 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.altoslib_8; + +import java.io.*; + +public interface AltosImage { +	/* Discard storage for image */ +	public abstract void flush(); +} diff --git a/altoslib/AltosKML.java b/altoslib/AltosKML.java index aa80fc21..81433958 100644 --- a/altoslib/AltosKML.java +++ b/altoslib/AltosKML.java @@ -15,14 +15,25 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*; +import java.util.*; + +class KMLWriter extends PrintWriter { +	public PrintWriter printf(String format, Object ... arguments) { +		return printf(Locale.ROOT, format, arguments); +	} + +	public KMLWriter(File name) throws FileNotFoundException { +		super(name); +	} +}  public class AltosKML implements AltosWriter {  	File			name; -	PrintStream		out; +	PrintWriter		out;  	int			flight_state = -1;  	AltosState		prev = null;  	double			gps_start_altitude; @@ -137,6 +148,10 @@ public class AltosKML implements AltosWriter {  			end();  			prev = null;  		} +		if (out != null) { +			out.close(); +			out = null; +		}  	}  	public void write(AltosState state) { @@ -177,7 +192,7 @@ public class AltosKML implements AltosWriter {  	public AltosKML(File in_name) throws FileNotFoundException {  		name = in_name; -		out = new PrintStream(name); +		out = new KMLWriter(name);  	}  	public AltosKML(String in_string) throws FileNotFoundException { diff --git a/altoslib/AltosLatLon.java b/altoslib/AltosLatLon.java new file mode 100644 index 00000000..e438a787 --- /dev/null +++ b/altoslib/AltosLatLon.java @@ -0,0 +1,46 @@ +/* + * Copyright © 2014 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.altoslib_8; + +public class AltosLatLon { +	public double	lat; +	public double	lon; + +	public int hashCode() { +		return new Double(lat).hashCode() ^ new Double(lon).hashCode(); +	} + +	public boolean equals(Object o) { +		if (o == null) +			return false; +		if (!(o instanceof AltosLatLon)) +			return false; + +		AltosLatLon other = (AltosLatLon) o; +		return lat == other.lat && lon == other.lon; +	} + +	public String toString() { +		return String.format("%f/%f", lat, lon); +	} + +	public AltosLatLon(double lat, double lon) { +		this.lat = lat; +		this.lon = lon; +	} +} diff --git a/altoslib/AltosLatitude.java b/altoslib/AltosLatitude.java index 191a46ee..7091ce9c 100644 --- a/altoslib/AltosLatitude.java +++ b/altoslib/AltosLatitude.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public class AltosLatitude extends AltosLocation {  	public String pos() { return "N"; } diff --git a/altoslib/AltosLaunchSite.java b/altoslib/AltosLaunchSite.java new file mode 100644 index 00000000..0fa9bbd4 --- /dev/null +++ b/altoslib/AltosLaunchSite.java @@ -0,0 +1,57 @@ +/* + * 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.altoslib_8; + +import java.io.*; +import java.lang.*; +import java.util.*; +import java.text.*; +import java.util.concurrent.*; + +public class AltosLaunchSite { +	public String	name; +	public double	latitude; +	public double	longitude; + +	public String toString() { +		return name; +	} + +	public AltosLaunchSite(String in_name, double in_latitude, double in_longitude) { +		name = in_name; +		latitude = in_latitude; +		longitude = in_longitude; +	} + +	public AltosLaunchSite(String line) throws ParseException { +		String[]	elements = line.split(":"); + +		if (elements.length < 3) +			throw new ParseException(String.format("Invalid site line %s", line), 0); + +		name = elements[0]; + +		try { +			latitude = AltosParse.parse_double_net(elements[1]); +			longitude = AltosParse.parse_double_net(elements[2]); +		} catch (ParseException pe) { +			throw new ParseException(String.format("Invalid site line %s", line), 0); +		} +	} +} + diff --git a/altoslib/AltosLaunchSiteListener.java b/altoslib/AltosLaunchSiteListener.java new file mode 100644 index 00000000..f4658660 --- /dev/null +++ b/altoslib/AltosLaunchSiteListener.java @@ -0,0 +1,26 @@ +/* + * 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.altoslib_8; + +import java.io.*; +import java.lang.*; +import java.util.*; +import java.util.concurrent.*; + +public interface AltosLaunchSiteListener { +	public abstract void notify_launch_sites(List<AltosLaunchSite> sites); +} diff --git a/altoslib/AltosLaunchSites.java b/altoslib/AltosLaunchSites.java new file mode 100644 index 00000000..fa4026ba --- /dev/null +++ b/altoslib/AltosLaunchSites.java @@ -0,0 +1,73 @@ +/* + * 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.altoslib_8; + +import java.io.*; +import java.lang.*; +import java.util.*; +import java.util.concurrent.*; +import java.net.*; +import java.text.*; + +public class AltosLaunchSites extends Thread { +	URL				url; +	LinkedList<AltosLaunchSite>	sites; +	AltosLaunchSiteListener		listener; + +	void notify_complete() { +		listener.notify_launch_sites(sites); +	} + +	void add(AltosLaunchSite site) { +		sites.add(site); +	} + +	void add(String line) { +		try { +			add(new AltosLaunchSite(line)); +		} catch (ParseException pe) { +			System.out.printf("parse exception %s\n", pe.toString()); +		} +	} + +	public void run() { +		try { +			url = new URL(AltosLib.launch_sites_url); +			URLConnection uc = url.openConnection(); + +			InputStreamReader in_stream = new InputStreamReader(uc.getInputStream(), AltosLib.unicode_set); +			BufferedReader in = new BufferedReader(in_stream); + +			for (;;) { +				String line = in.readLine(); +				if (line == null) +					break; +				add(line); +			} +		} catch (Exception e) { +		} finally { +			notify_complete(); +		} +	} + +	public AltosLaunchSites(AltosLaunchSiteListener listener) { +		sites = new LinkedList<AltosLaunchSite>(); +		this.listener = listener; +		start(); +	} +} diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index b19f9f52..e82b1c73 100644 --- a/altoslib/AltosLib.java +++ b/altoslib/AltosLib.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.util.*;  import java.io.*; @@ -190,6 +190,13 @@ public class AltosLib {  		38400, 9600, 2400  	}; +	public static final int ao_aprs_format_compressed = 0; +	public static final int ao_aprs_format_uncompressed = 1; + +	public static final String[] ao_aprs_format_name = { +		"Compressed", "Uncompressed" +	}; +  	public static final String launch_sites_url = "http://www.altusmetrum.org/AltOS/launch-sites.txt";  //	public static final String launch_sites_url = "file:///home/keithp/misc/text/altusmetrum/AltOS/launch-sites.txt"; diff --git a/altoslib/AltosLine.java b/altoslib/AltosLine.java index a65ba593..b18aa965 100644 --- a/altoslib/AltosLine.java +++ b/altoslib/AltosLine.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public class AltosLine {  	public String	line; diff --git a/altoslib/AltosLink.java b/altoslib/AltosLink.java index 01c37864..f8bf4702 100644 --- a/altoslib/AltosLink.java +++ b/altoslib/AltosLink.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*;  import java.util.concurrent.*; @@ -86,10 +86,17 @@ public abstract class AltosLink implements Runnable {  	public boolean	reply_abort;  	public int	in_reply; +	boolean	cancel_enable = true; + +	public void set_cancel_enable(boolean e) { +		cancel_enable = e; +	}  	boolean		reply_timeout_shown = false;  	private boolean check_reply_timeout() { +		if (!cancel_enable) +			return false;  		if (!reply_timeout_shown)  			reply_timeout_shown = show_reply_timeout();  		return reply_abort; @@ -354,7 +361,7 @@ public abstract class AltosLink implements Runnable {  		if (frequency == 0)  			return;  		if (has_frequency) -			set_radio_freq((int) Math.floor (frequency * 1000)); +			set_radio_freq((int) Math.floor (frequency * 1000 + 0.5));  		else if (has_setting)  			set_radio_setting(AltosConvert.radio_frequency_to_setting(frequency, cal));  		else @@ -546,7 +553,15 @@ public abstract class AltosLink implements Runnable {  		}  		if (monitor_batt == AltosLib.MISSING)  			return AltosLib.MISSING; -		return AltosConvert.cc_battery_to_voltage(monitor_batt); + +		double	volts = AltosLib.MISSING; +		if (config_data.product.startsWith("TeleBT-v3")) { +			volts = AltosConvert.tele_bt_3_battery(monitor_batt); +		} else { +			volts = AltosConvert.cc_battery_to_voltage(monitor_batt); +		} + +		return volts;  	}  	public AltosLink() { diff --git a/altoslib/AltosListenerState.java b/altoslib/AltosListenerState.java index d7e18008..9d7922d5 100644 --- a/altoslib/AltosListenerState.java +++ b/altoslib/AltosListenerState.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*; diff --git a/altoslib/AltosLocation.java b/altoslib/AltosLocation.java index b21014db..231cd94b 100644 --- a/altoslib/AltosLocation.java +++ b/altoslib/AltosLocation.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public abstract class AltosLocation extends AltosUnits { diff --git a/altoslib/AltosLog.java b/altoslib/AltosLog.java index 9241581a..b89bac38 100644 --- a/altoslib/AltosLog.java +++ b/altoslib/AltosLog.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*;  import java.text.*; diff --git a/altoslib/AltosLongitude.java b/altoslib/AltosLongitude.java index ff4f0c2b..e3e53282 100644 --- a/altoslib/AltosLongitude.java +++ b/altoslib/AltosLongitude.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public class AltosLongitude extends AltosLocation {  	public String pos() { return "E"; } diff --git a/altoslib/AltosMag.java b/altoslib/AltosMag.java index f7595639..351125bf 100644 --- a/altoslib/AltosMag.java +++ b/altoslib/AltosMag.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.util.concurrent.*;  import java.io.*; diff --git a/altoslib/AltosMap.java b/altoslib/AltosMap.java new file mode 100644 index 00000000..8a3266c9 --- /dev/null +++ b/altoslib/AltosMap.java @@ -0,0 +1,485 @@ +/* + * Copyright © 2010 Anthony Towns <aj@erisian.com.au> + * + * 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.altoslib_8; + +import java.io.*; +import java.lang.*; +import java.util.*; +import java.util.concurrent.*; + +public class AltosMap implements AltosMapTileListener, AltosMapStoreListener { + +	public static final int px_size = 512; + +	public static final int maptype_hybrid = 0; +	public static final int maptype_roadmap = 1; +	public static final int maptype_satellite = 2; +	public static final int maptype_terrain = 3; +	public static final int maptype_default = maptype_hybrid; + +	public static final int default_zoom = 15; +	public static final int min_zoom = 3; +	public static final int max_zoom = 21; + +	public static final String[] maptype_names = { +		"hybrid", +		"roadmap", +		"satellite", +		"terrain" +	}; + +	public static final String[] maptype_labels = { +		"Hybrid", +		"Roadmap", +		"Satellite", +		"Terrain" +	}; + +	AltosMapInterface	map_interface; + +	AltosMapCache		cache; + +	public AltosMapCache cache() { return cache; } + +	LinkedList<AltosMapMark> marks = new LinkedList<AltosMapMark>(); + +	AltosMapPath		path; +	AltosMapLine		line; +	public AltosLatLon	last_position; + +	boolean		have_boost = false; +	boolean		have_landed = false; + +	ConcurrentHashMap<AltosPointInt,AltosMapTile> tiles = new ConcurrentHashMap<AltosPointInt,AltosMapTile>(); +	int		load_radius; +	AltosLatLon	load_centre = null; +	AltosMapTileListener	load_listener; + +	int 		zoom = AltosMap.default_zoom; +	int		maptype = AltosMap.maptype_default; + +	long		user_input_time; + +	/* Milliseconds to wait after user action before auto-scrolling +	 */ +	static final long auto_scroll_delay = 20 * 1000; + +	public AltosMapTransform	transform; +	AltosLatLon		centre; + +	public void reset() { +		// nothing +	} + +	/* MapInterface wrapping functions */ + +	public void repaint(int x, int y, int w, int h) { +		map_interface.repaint(new AltosRectangle(x, y, w, h)); +	} + +	public void repaint(AltosMapRectangle damage, int pad) { +		AltosRectangle r = transform.screen(damage); +		repaint(r.x - pad, r.y - pad, r.width + pad * 2, r.height + pad * 2); +	} + +	public void repaint() { +		map_interface.repaint(); +	} + +	public int width() { +		return map_interface.width(); +	} + +	public int height() { +		return map_interface.height(); +	} + +	public void debug(String format, Object ... arguments) { +		map_interface.debug(format, arguments); +	} + +	static public AltosPointInt floor(AltosPointDouble point) { +		return new AltosPointInt ((int) Math.floor(point.x / AltosMap.px_size) * AltosMap.px_size, +					      (int) Math.floor(point.y / AltosMap.px_size) * AltosMap.px_size); +	} + +	static public AltosPointInt ceil(AltosPointDouble point) { +		return new AltosPointInt ((int) Math.ceil(point.x / AltosMap.px_size) * AltosMap.px_size, +					      (int) Math.ceil(point.y / AltosMap.px_size) * AltosMap.px_size); +	} + +	public void notice_user_input() { +		user_input_time = System.currentTimeMillis(); +	} + +	public boolean recent_user_input() { +		return (System.currentTimeMillis() - user_input_time) < auto_scroll_delay; +	} + +	public boolean has_centre() { +		return centre != null; +	} + +	public boolean far_from_centre(AltosLatLon lat_lon) { + +		if (centre == null || transform == null) +			return true; + +		AltosPointDouble	screen = transform.screen(lat_lon); + +		int		width = width(); +		int		dx = Math.abs ((int) (double) screen.x - width/2); + +		if (dx > width / 4) +			return true; + +		int		height = height(); +		int		dy = Math.abs ((int) (double) screen.y - height/2); + +		if (dy > height / 4) +			return true; + +		return false; +	} + +	public void set_transform() { +		if (centre != null) { +			transform = new AltosMapTransform(width(), height(), zoom, centre); +			repaint(); +		} +	} + +	private void set_zoom_label() { +		map_interface.set_zoom_label(String.format("Zoom %d", get_zoom() - default_zoom)); +	} + + +	public boolean set_zoom(int zoom) { +		notice_user_input(); +		if (AltosMap.min_zoom <= zoom && zoom <= AltosMap.max_zoom && zoom != this.zoom) { +			this.zoom = zoom; +			tiles.clear(); +			set_transform(); +			set_zoom_label(); +			return true; +		} +		return false; +	} + +	public boolean set_zoom_centre(int zoom, AltosPointInt centre) { +		AltosLatLon	mouse_lat_lon = null; +		boolean		ret; + +		if (transform != null) +			mouse_lat_lon = transform.screen_lat_lon(centre); + +		ret = set_zoom(zoom); + +		if (ret && mouse_lat_lon != null) { +			AltosPointDouble	new_mouse = transform.screen(mouse_lat_lon); + +			double	dx = width()/2.0 - centre.x; +			double	dy = height()/2.0 - centre.y; + +			AltosLatLon	new_centre = transform.screen_lat_lon(new AltosPointDouble(new_mouse.x + dx, new_mouse.y + dy)); + +			centre(new_centre); +		} + +		return ret; +	} + +	public int get_zoom() { +		return zoom; +	} + +	public boolean set_maptype(int maptype) { +		if (maptype != this.maptype) { +			this.maptype = maptype; +			tiles.clear(); +			repaint(); +			return true; +		} +		return false; +	} + +	public void show(AltosState state, AltosListenerState listener_state) { + +		/* If insufficient gps data, nothing to update +		 */ +		AltosGPS	gps = state.gps; + +		if (gps == null) +			return; + +		if (!gps.locked && gps.nsat < 4) +			return; + +		switch (state.state) { +		case AltosLib.ao_flight_boost: +			if (!have_boost) { +				add_mark(gps.lat, gps.lon, state.state); +				have_boost = true; +			} +			break; +		case AltosLib.ao_flight_landed: +			if (!have_landed) { +				add_mark(gps.lat, gps.lon, state.state); +				have_landed = true; +			} +			break; +		} + +		if (path != null) { +			AltosMapRectangle	damage = path.add(gps.lat, gps.lon, state.state); + +			if (damage != null) +				repaint(damage, AltosMapPath.stroke_width); +		} + +		last_position = new AltosLatLon(gps.lat, gps.lon); + +		maybe_centre(gps.lat, gps.lon); +	} + +	public void centre(AltosLatLon lat_lon) { +		centre = lat_lon; +		set_transform(); +	} + +	public void centre(double lat, double lon) { +		centre(new AltosLatLon(lat, lon)); +	} + +	public void centre(AltosState state) { +		if (!state.gps.locked && state.gps.nsat < 4) +			return; +		centre(state.gps.lat, state.gps.lon); +	} + +	public void maybe_centre(double lat, double lon) { +		AltosLatLon	lat_lon = new AltosLatLon(lat, lon); +		if (centre == null || (!recent_user_input() && far_from_centre(lat_lon))) +			centre(lat_lon); +	} + +	public void add_mark(double lat, double lon, int state) { +		synchronized(marks) { +			AltosMapMark mark = map_interface.new_mark(lat, lon, state); +			if (mark != null) +				marks.add(mark); +		} +		repaint(); +	} + +	public void clear_marks() { +		synchronized(marks) { +			marks.clear(); +		} +	} + +	private void make_tiles() { +		AltosPointInt	upper_left; +		AltosPointInt	lower_right; + +		if (load_centre != null) { +			AltosPointInt centre = 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); +		} else { +			upper_left = floor(transform.screen_point(new AltosPointInt(0, 0))); +			lower_right = floor(transform.screen_point(new AltosPointInt(width(), height()))); +		} +		for (AltosPointInt point : tiles.keySet()) { +			if (point.x < upper_left.x || lower_right.x < point.x || +			    point.y < upper_left.y || lower_right.y < point.y) { +				tiles.remove(point); +			} +		} + +		cache.set_cache_size((width() / AltosMap.px_size + 2) * (height() / AltosMap.px_size + 2)); + +		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) { +				AltosPointInt	point = new AltosPointInt(x, y); + +				if (!tiles.containsKey(point)) { +					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_interface.new_tile(this, ul, center, zoom, maptype, px_size); +					tiles.put(point, tile); +				} +			} +		} +	} + +	public void set_load_params(int new_zoom, int new_type, double lat, double lon, int radius, AltosMapTileListener listener) { +		if (AltosMap.min_zoom <= new_zoom && new_zoom <= AltosMap.max_zoom) +			zoom = new_zoom; +		maptype = new_type; +		load_centre = new AltosLatLon(lat, lon); +		load_radius = radius; +		load_listener = listener; +		centre(lat, lon); +		tiles.clear(); +		make_tiles(); +		for (AltosMapTile tile : tiles.values()) { +			tile.add_store_listener(this); +			if (tile.store_status() != AltosMapTile.loading) +				listener.notify_tile(tile, tile.store_status()); +		} +		repaint(); +	} + +	public String getName() { +		return "Map"; +	} + +	public void paint() { +		if (centre != null) +			make_tiles(); + +		if (transform == null) +			return; + +		for (AltosMapTile tile : tiles.values()) +			tile.paint(transform); + +		synchronized(marks) { +			for (AltosMapMark mark : marks) +				mark.paint(transform); +		} + +		if (path != null) +			path.paint(transform); + +		if (line != null) +			line.paint(transform); +	} + +	/* AltosMapTileListener methods */ +	public synchronized void notify_tile(AltosMapTile tile, int status) { +		for (AltosPointInt point : tiles.keySet()) { +			if (tile == tiles.get(point)) { +				AltosPointInt	screen = transform.screen(point); +				repaint(screen.x, screen.y, AltosMap.px_size, AltosMap.px_size); +			} +		} +	} + +	/* AltosMapStoreListener methods */ +	public synchronized void notify_store(AltosMapStore store, int status) { +		if (load_listener != null) { +			for (AltosMapTile tile : tiles.values()) +				if (store.equals(tile.store)) +					load_listener.notify_tile(tile, status); +		} +	} + +	/* UI elements */ + +	AltosPointInt	drag_start; + +	boolean		dragged; + +	static final double drag_far = 20; + +	private void drag(int x, int y) { +		if (drag_start == null) +			return; + +		int dx = x - drag_start.x; +		int dy = y - drag_start.y; + +		double distance = Math.hypot(dx, dy); + +		if (distance > drag_far) +			dragged = true; + +		if (transform == null) { +			debug("Transform not set in drag\n"); +			return; +		} + +		AltosLatLon new_centre = transform.screen_lat_lon(new AltosPointInt(width() / 2 - dx, height() / 2 - dy)); +		centre(new_centre); +		drag_start = new AltosPointInt(x, y); +	} + +	private void drag_start(int x, int y) { +		drag_start = new AltosPointInt(x, y); +		dragged = false; +	} + +	private void drag_stop(int x, int y) { +		if (!dragged) { +			if (transform == null) { +				debug("Transform not set in stop\n"); +				return; +			} +			map_interface.select_object (transform.screen_lat_lon(new AltosPointInt(x,y))); +		} +	} + +	private void line_start(int x, int y) { +		if (line != null) { +			line.pressed(new AltosPointInt(x, y), transform); +			repaint(); +		} +	} + +	private void line(int x, int y) { +		if (line != null) { +			line.dragged(new AltosPointInt(x, y), transform); +			repaint(); +		} +	} + +	public void touch_start(int x, int y, boolean is_drag) { +		notice_user_input(); +		if (is_drag) +			drag_start(x, y); +		else +			line_start(x, y); +	} + +	public void touch_continue(int x, int y, boolean is_drag) { +		notice_user_input(); +		if (is_drag) +			drag(x, y); +		else +			line(x, y); +	} + +	public void touch_stop(int x, int y, boolean is_drag) { +		notice_user_input(); +		if (is_drag) +			drag_stop(x, y); +	} + +	public AltosMap(AltosMapInterface map_interface) { +		this.map_interface = map_interface; +		cache = new AltosMapCache(map_interface); +		line = map_interface.new_line(); +		path = map_interface.new_path(); +		set_zoom_label(); +	} +} diff --git a/altoslib/AltosMapCache.java b/altoslib/AltosMapCache.java new file mode 100644 index 00000000..f0ad433c --- /dev/null +++ b/altoslib/AltosMapCache.java @@ -0,0 +1,207 @@ +/* + * Copyright © 2010 Anthony Towns <aj@erisian.com.au> + * + * 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.altoslib_8; + +import java.io.*; +import java.net.*; + +public class AltosMapCache implements AltosMapCacheListener { + +	/* An entry in the MapCache */ +	class MapCacheElement implements AltosMapStoreListener { + +		AltosMapTile		tile;		/* Notify when image has been loaded */ +		AltosImage		image; +		AltosMapStore		store; +		long			used; + +		class loader implements Runnable { +			public void run() { +				if (image != null) +					tile.notify_image(image); +				try { +					image = map_interface.load_image(store.file); +				} catch (Exception ex) { +				} +				if (image == null) +					tile.set_status(AltosMapTile.failed); +				else +					tile.set_status(AltosMapTile.success); +				tile.notify_image(image); +			} +		} + +		private void load() { +			loader	l = new loader(); +			Thread	lt = new Thread(l); +			lt.start(); +		} + +		public void flush() { +			if (image != null) { +				image.flush(); +				image = null; +			} +		} + +		public boolean has_map() { +			return store.status() == AltosMapTile.success; +		} + +		public synchronized void notify_store(AltosMapStore store, int status) { +			switch (status) { +			case AltosMapTile.loading: +				break; +			case AltosMapTile.success: +				load(); +				break; +			default: +				tile.set_status(status); +				tile.notify_image(null); +			} +		} + +		public MapCacheElement(AltosMapTile tile, AltosMapStore store) throws IOException { +			this.tile = tile; +			this.image = null; +			this.store = store; +			this.used = 0; + +			int status = store.status(); +			switch (status) { +			case AltosMapTile.loading: +				store.add_listener(this); +				break; +			case AltosMapTile.success: +				load(); +				break; +			default: +				tile.set_status(status); +				tile.notify_image(null); +				break; +			} +		} +	} + +	int			min_cache_size;		/* configured minimum cache size */ +	int			cache_size;		/* current cache size */ +	int			requested_cache_size;	/* cache size computed by application */ + +	private Object 		fetch_lock = new Object(); +	private Object 		cache_lock = new Object(); + +	AltosMapInterface	map_interface; + +	MapCacheElement[]	elements = new MapCacheElement[cache_size]; + +	long			used; + +	public void set_cache_size(int new_size) { + +		requested_cache_size = new_size; + +		if (new_size < min_cache_size) +			new_size = min_cache_size; + +		if (new_size == cache_size) +			return; + +		synchronized(cache_lock) { +			MapCacheElement[]	new_elements = new MapCacheElement[new_size]; + +			for (int i = 0; i < cache_size; i++) { +				if (i < new_size) +					new_elements[i] = elements[i]; +				else if (elements[i] != null) +					elements[i].flush(); +			} +			elements = new_elements; +			cache_size = new_size; +		} +	} + +	public AltosImage get(AltosMapTile tile, AltosMapStore store, int width, int height) { +		int		oldest = -1; +		long		age = used; + +		synchronized(cache_lock) { +			MapCacheElement	element = null; +			for (int i = 0; i < cache_size; i++) { +				element = elements[i]; + +				if (element == null) { +					oldest = i; +					break; +				} +				if (store.equals(element.store)) { +					element.used = used++; +					return element.image; +				} +				if (element.used < age) { +					oldest = i; +					age = element.used; +				} +			} + +			try { +				element = new MapCacheElement(tile, store); +				element.used = used++; +				if (elements[oldest] != null) +					elements[oldest].flush(); + +				elements[oldest] = element; + +				if (element.image == null) +					tile.set_status(AltosMapTile.loading); +				else +					tile.set_status(AltosMapTile.success); + +				return element.image; +			} catch (IOException e) { +				tile.set_status(AltosMapTile.failed); +				return null; +			} +		} +	} + +	public void map_cache_changed(int map_cache) { +		min_cache_size = map_cache; + +		set_cache_size(requested_cache_size); +	} + +	public void dispose() { +		AltosPreferences.unregister_map_cache_listener(this); + +		for (int i = 0; i < cache_size; i++) { +			MapCacheElement element = elements[i]; + +			if (element != null) +			    element.flush(); +		} +	} + +	public AltosMapCache(AltosMapInterface map_interface) { +		this.map_interface = map_interface; +		min_cache_size = AltosPreferences.map_cache(); + +		set_cache_size(0); + +		AltosPreferences.register_map_cache_listener(this); +	} +} diff --git a/altoslib/AltosMapCacheListener.java b/altoslib/AltosMapCacheListener.java new file mode 100644 index 00000000..dec181bc --- /dev/null +++ b/altoslib/AltosMapCacheListener.java @@ -0,0 +1,22 @@ +/* + * Copyright © 2014 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.altoslib_8; + +public interface AltosMapCacheListener { +	public void map_cache_changed(int map_cache); +} diff --git a/altoslib/AltosMapInterface.java b/altoslib/AltosMapInterface.java new file mode 100644 index 00000000..45398ecd --- /dev/null +++ b/altoslib/AltosMapInterface.java @@ -0,0 +1,47 @@ +/* + * 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.altoslib_8; + +import java.io.*; +import java.net.*; + +public interface AltosMapInterface { +	public abstract AltosMapPath new_path(); + +	public abstract AltosMapLine new_line(); + +	public abstract AltosImage load_image(File file) throws Exception; + +	public abstract AltosMapMark new_mark(double lat, double lon, int state); + +	public abstract AltosMapTile new_tile(AltosMapTileListener listener, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size); + +	public abstract int width(); + +	public abstract int height(); + +	public abstract void repaint(); + +	public abstract void repaint(AltosRectangle damage); + +	public abstract void set_zoom_label(String label); + +	public abstract void debug(String format, Object ... arguments); + +	public abstract void select_object(AltosLatLon latlon); +} diff --git a/altoslib/AltosMapLine.java b/altoslib/AltosMapLine.java new file mode 100644 index 00000000..09ecb0c9 --- /dev/null +++ b/altoslib/AltosMapLine.java @@ -0,0 +1,81 @@ +/* + * Copyright © 2014 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.altoslib_8; + +import java.io.*; +import java.lang.Math; +import java.util.*; +import java.util.concurrent.*; + +public abstract class AltosMapLine { +	public AltosLatLon	start, end; + +	static public int stroke_width = 6; + +	public abstract void paint(AltosMapTransform t); + +	private AltosLatLon lat_lon(AltosPointInt pt, AltosMapTransform t) { +		return t.screen_lat_lon(pt); +	} + +	public void dragged(AltosPointInt pt, AltosMapTransform t) { +		end = lat_lon(pt, t); +	} + +	public void pressed(AltosPointInt pt, AltosMapTransform t) { +		start = lat_lon(pt, t); +		end = null; +	} + +	public String line_dist() { +		String	format; +		AltosGreatCircle	g = new AltosGreatCircle(start.lat, start.lon, +								 end.lat, end.lon); +		double	distance = g.distance; + +		if (AltosConvert.imperial_units) { +			distance = AltosConvert.meters_to_feet(distance); +			if (distance < 10000) { +				format = "%4.0fft"; +			} else { +				distance /= 5280; +				if (distance < 10) +					format = "%5.3fmi"; +				else if (distance < 100) +					format = "%5.2fmi"; +				else if (distance < 1000) +					format = "%5.1fmi"; +				else +					format = "%5.0fmi"; +			} +		} else { +			if (distance < 10000) { +				format = "%4.0fm"; +			} else { +				distance /= 1000; +				if (distance < 100) +					format = "%5.2fkm"; +				else if (distance < 1000) +					format = "%5.1fkm"; +				else +					format = "%5.0fkm"; +			} +		} +		return String.format(format, distance); +	} +} diff --git a/altoslib/AltosMapLoader.java b/altoslib/AltosMapLoader.java new file mode 100644 index 00000000..8573489a --- /dev/null +++ b/altoslib/AltosMapLoader.java @@ -0,0 +1,205 @@ +/* + * 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.altoslib_8; + +import java.io.*; +import java.util.*; +import java.text.*; +import java.lang.Math; +import java.net.URL; +import java.net.URLConnection; + +public class AltosMapLoader implements AltosMapTileListener, AltosMapStoreListener { +	AltosMapLoaderListener	listener; + +	double	latitude, longitude; +	int	min_z; +	int	max_z; +	int	cur_z; +	int	all_types; +	int	cur_type; +	double	radius; + +	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() { +		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) { +		int next_type; +		for (next_type = start; +		     next_type <= AltosMap.maptype_terrain && (all_types & (1 << next_type)) == 0; +		     next_type++) +			; +		return next_type; +	} + +	public void next_load() { +		int next_type = next_type(cur_type + 1); + +		if (next_type > AltosMap.maptype_terrain) { +			if (cur_z == max_z) { +				return; +			} else { +				cur_z++; +			} +			next_type = next_type(0); +		} +		cur_type = next_type; +		do_load(); +	} + +	private void start_load() { + +		cur_z = min_z; +		int ntype = 0; + +		for (int t = AltosMap.maptype_hybrid; t <= AltosMap.maptype_terrain; t++) +			if ((all_types & (1 << t)) != 0) +				ntype++; +		if (ntype == 0) { +			all_types = (1 << AltosMap.maptype_hybrid); +			ntype = 1; +		} + +		cur_type = next_type(0); + +		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_total = 0; + +		listener.debug("total tiles %d\n", tiles_total); + +		listener.loader_start(tiles_total); +		do_load(); +	} + +	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; +		this.max_z = max_z; +		this.radius = radius; +		this.all_types = all_types; +		start_load(); +	} + +	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_total; +		++tiles_loaded_layer; +		listener.debug("total %d layer %d\n", tiles_loaded_total, tiles_loaded_layer); + +		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(tiles_total); +				return; +			} else { +				do_next = true; +			} +		} +		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) { +		this.map = map; +		this.listener = listener; +	} +} diff --git a/altoslib/AltosMapLoaderListener.java b/altoslib/AltosMapLoaderListener.java new file mode 100644 index 00000000..0b41d9f4 --- /dev/null +++ b/altoslib/AltosMapLoaderListener.java @@ -0,0 +1,28 @@ +/* + * 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.altoslib_8; + +public interface AltosMapLoaderListener { +	public abstract void loader_start(int max); + +	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); +} diff --git a/altoslib/AltosMapMark.java b/altoslib/AltosMapMark.java new file mode 100644 index 00000000..cc28f438 --- /dev/null +++ b/altoslib/AltosMapMark.java @@ -0,0 +1,38 @@ +/* + * Copyright © 2014 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.altoslib_8; + +import java.io.*; +import java.lang.Math; +import java.util.*; +import java.util.concurrent.*; + +public abstract class AltosMapMark { + +	public AltosLatLon	lat_lon; +	public int		state; + +	static public int stroke_width = 6; + +	public abstract void paint(AltosMapTransform t); + +	public AltosMapMark (double lat, double lon, int state) { +		lat_lon = new AltosLatLon(lat, lon); +		this.state = state; +	} +} diff --git a/altoslib/AltosMapPath.java b/altoslib/AltosMapPath.java new file mode 100644 index 00000000..6967f479 --- /dev/null +++ b/altoslib/AltosMapPath.java @@ -0,0 +1,50 @@ +/* + * Copyright © 2014 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.altoslib_8; + +import java.io.*; +import java.lang.Math; +import java.util.*; +import java.util.concurrent.*; + +public abstract class AltosMapPath { + +	public LinkedList<AltosMapPathPoint>	points = new LinkedList<AltosMapPathPoint>(); +	public AltosMapPathPoint		last_point = null; + +	static public int stroke_width = 6; + +	public abstract void paint(AltosMapTransform t); + +	public AltosMapRectangle add(double lat, double lon, int state) { +		AltosMapPathPoint		point = new AltosMapPathPoint(new AltosLatLon (lat, lon), state); +		AltosMapRectangle	rect = null; + +		if (!point.equals(last_point)) { +			if (last_point != null) +				rect = new AltosMapRectangle(last_point.lat_lon, point.lat_lon); +			points.add (point); +			last_point = point; +		} +		return rect; +	} + +	public void clear () { +		points = new LinkedList<AltosMapPathPoint>(); +	} +} diff --git a/altoslib/AltosMapPathPoint.java b/altoslib/AltosMapPathPoint.java new file mode 100644 index 00000000..0af98997 --- /dev/null +++ b/altoslib/AltosMapPathPoint.java @@ -0,0 +1,50 @@ +/* + * 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.altoslib_8; + +import java.io.*; +import java.lang.Math; +import java.util.*; +import java.util.concurrent.*; + +public class AltosMapPathPoint { +	public AltosLatLon	lat_lon; +	public int		state; + +	public int hashCode() { +		return lat_lon.hashCode() ^ state; +	} + +	public boolean equals(Object o) { +		if (o == null) +			return false; + +		if (!(o instanceof AltosMapPathPoint)) +			return false; + +		AltosMapPathPoint other = (AltosMapPathPoint) o; + +		return lat_lon.equals(other.lat_lon) && state == other.state; +	} + +	public AltosMapPathPoint(AltosLatLon lat_lon, int state) { +		this.lat_lon = lat_lon; +		this.state = state; +	} +} + diff --git a/altoslib/AltosMapRectangle.java b/altoslib/AltosMapRectangle.java new file mode 100644 index 00000000..9fdab1a0 --- /dev/null +++ b/altoslib/AltosMapRectangle.java @@ -0,0 +1,45 @@ +/* + * Copyright © 2014 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.altoslib_8; + +public class AltosMapRectangle { +	AltosLatLon	ul, lr; + +	public AltosMapRectangle(AltosLatLon a, AltosLatLon b) { +		double	ul_lat, ul_lon; +		double	lr_lat, lr_lon; + +		if (a.lat > b.lat) { +			ul_lat = a.lat; +			lr_lat = b.lat; +		} else { +			ul_lat = b.lat; +			lr_lat = a.lat; +		} +		if (a.lon < b.lon) { +			ul_lon = a.lon; +			lr_lon = b.lon; +		} else { +			ul_lon = b.lon; +			lr_lon = a.lon; +		} + +		ul = new AltosLatLon(ul_lat, ul_lon); +		lr = new AltosLatLon(lr_lat, lr_lon); +	} +} diff --git a/altoslib/AltosMapStore.java b/altoslib/AltosMapStore.java new file mode 100644 index 00000000..b24fabc8 --- /dev/null +++ b/altoslib/AltosMapStore.java @@ -0,0 +1,243 @@ +/* + * Copyright © 2014 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.altoslib_8; + +import java.io.*; +import java.net.*; +import java.util.*; + +public class AltosMapStore { +	String					url; +	public File				file; +	LinkedList<AltosMapStoreListener>	listeners = new LinkedList<AltosMapStoreListener>(); + +	int					status; + +	public int status() { +		return status; +	} + +	public synchronized void add_listener(AltosMapStoreListener listener) { +		if (!listeners.contains(listener)) +			listeners.add(listener); +	} + +	public synchronized void remove_listener(AltosMapStoreListener listener) { +		listeners.remove(listener); +	} + +	private synchronized void notify_listeners(int status) { +		this.status = status; +		for (AltosMapStoreListener listener : listeners) +			listener.notify_store(this, status); +	} + +	static Object	forbidden_lock = new Object(); +	static long	forbidden_time; +	static boolean	forbidden_set; + +	private int fetch_url() { +		URL u; + +		try { +			u = new URL(url); +		} catch (java.net.MalformedURLException e) { +			return AltosMapTile.bad_request; +		} + +		byte[] data; +		URLConnection uc = null; +		try { +			uc = u.openConnection(); +			String type = uc.getContentType(); +			int contentLength = uc.getContentLength(); +			if (uc instanceof HttpURLConnection) { +				int response = ((HttpURLConnection) uc).getResponseCode(); +				switch (response) { +				case HttpURLConnection.HTTP_FORBIDDEN: +				case HttpURLConnection.HTTP_PAYMENT_REQUIRED: +				case HttpURLConnection.HTTP_UNAUTHORIZED: +					synchronized (forbidden_lock) { +						forbidden_time = System.nanoTime(); +						forbidden_set = true; +						return AltosMapTile.forbidden; +					} +				} +			} +			InputStream in = new BufferedInputStream(uc.getInputStream()); +			int bytesRead = 0; +			int offset = 0; +			data = new byte[contentLength]; +			while (offset < contentLength) { +				bytesRead = in.read(data, offset, data.length - offset); +				if (bytesRead == -1) +					break; +				offset += bytesRead; +			} +			in.close(); + +			if (offset != contentLength) +				return AltosMapTile.failed; + +		} catch (IOException e) { +			return AltosMapTile.failed; +		} + +		try { +			FileOutputStream out = new FileOutputStream(file); +			out.write(data); +			out.flush(); +			out.close(); +		} catch (FileNotFoundException e) { +			return AltosMapTile.bad_request; +		} catch (IOException e) { +			if (file.exists()) +				file.delete(); +			return AltosMapTile.bad_request; +		} +		return AltosMapTile.success; +	} + +	static Object	fetch_lock = new Object(); + +	static final long	forbidden_interval = 60l * 1000l * 1000l * 1000l; +	static final long 	google_maps_ratelimit_ms = 1200; + +	static Object	loader_lock = new Object(); + +	static LinkedList<AltosMapStore> waiting = new LinkedList<AltosMapStore>(); +	static LinkedList<AltosMapStore> running = new LinkedList<AltosMapStore>(); + +	static final int concurrent_loaders = 128; + +	static void start_loaders() { +		while (!waiting.isEmpty() && running.size() < concurrent_loaders) { +			AltosMapStore 	s = waiting.remove(); +			running.add(s); +			Thread lt = s.make_loader_thread(); +			lt.start(); +		} +	} + +	void finish_loader() { +		synchronized(loader_lock) { +			running.remove(this); +			start_loaders(); +		} +	} + +	void add_loader() { +		synchronized(loader_lock) { +			waiting.add(this); +			start_loaders(); +		} +	} + +	class loader implements Runnable { + +		public void run() { +			try { +				if (file.exists()) { +					notify_listeners(AltosMapTile.success); +					return; +				} + +				synchronized(forbidden_lock) { +					if (forbidden_set && (System.nanoTime() - forbidden_time) < forbidden_interval) { +						notify_listeners(AltosMapTile.forbidden); +						return; +					} +				} + +				int new_status; + +				if (!AltosVersion.has_google_maps_api_key()) { +					synchronized (fetch_lock) { +						long startTime = System.nanoTime(); +						new_status = fetch_url(); +						if (new_status == AltosMapTile.success) { +							long duration_ms = (System.nanoTime() - startTime) / 1000000; +							if (duration_ms < google_maps_ratelimit_ms) { +								try { +									Thread.sleep(google_maps_ratelimit_ms - duration_ms); +								} catch (InterruptedException e) { +									Thread.currentThread().interrupt(); +								} +							} +						} +					} +				} else { +					new_status = fetch_url(); +				} +				notify_listeners(new_status); +			} finally { +				finish_loader(); +			} +		} +	} + +	private Thread make_loader_thread() { +		return new Thread(new loader()); +	} + +	private void load() { +		add_loader(); +	} + +	private AltosMapStore (String url, File file) { +		this.url = url; +		this.file = file; + +		if (file.exists()) +			status = AltosMapTile.success; +		else { +			status = AltosMapTile.loading; +			load(); +		} +	} + +	public int hashCode() { +		return url.hashCode(); +	} + +	public boolean equals(Object o) { +		if (o == null) +			return false; + +		if (!(o instanceof AltosMapStore)) +			return false; + +		AltosMapStore other = (AltosMapStore) o; +		return url.equals(other.url); +	} + +	static HashMap<String,AltosMapStore> stores = new HashMap<String,AltosMapStore>(); + +	public static AltosMapStore get(String url, File file) { +		AltosMapStore	store; +		synchronized(stores) { +			if (stores.containsKey(url)) { +				store = stores.get(url); +			} else { +				store = new AltosMapStore(url, file); +				stores.put(url, store); +			} +		} +		return store; +	} +} diff --git a/altoslib/AltosMapStoreListener.java b/altoslib/AltosMapStoreListener.java new file mode 100644 index 00000000..cef4f926 --- /dev/null +++ b/altoslib/AltosMapStoreListener.java @@ -0,0 +1,22 @@ +/* + * Copyright © 2014 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.altoslib_8; + +public interface AltosMapStoreListener { +	abstract void notify_store(AltosMapStore store, int status); +} diff --git a/altoslib/AltosMapTile.java b/altoslib/AltosMapTile.java new file mode 100644 index 00000000..a6ba5da5 --- /dev/null +++ b/altoslib/AltosMapTile.java @@ -0,0 +1,128 @@ +/* + * Copyright © 2010 Anthony Towns <aj@erisian.com.au> + * + * 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.altoslib_8; + +import java.io.*; +import java.util.*; + +public abstract class AltosMapTile implements AltosFontListener { +	AltosMapTileListener	listener; +	public AltosLatLon	upper_left, center; +	public int		px_size; +	int		zoom; +	int		maptype; +	int		scale; +	public AltosMapStore	store; +	public AltosMapCache	cache; +	public int	status; + +	static public final int	success = 0; +	static public final int	loading = 1; +	static public final int	failed = 2; +	static public final int	bad_request = 3; +	static public final int	forbidden = 4; + +	private File map_file() { +		double lat = center.lat; +		double lon = center.lon; +		char chlat = lat < 0 ? 'S' : 'N'; +		char chlon = lon < 0 ? 'W' : 'E'; + +		if (lat < 0) lat = -lat; +		if (lon < 0) lon = -lon; +		String maptype_string = String.format("%s-", AltosMap.maptype_names[maptype]); +		String format_string; +		if (maptype == AltosMap.maptype_hybrid || maptype == AltosMap.maptype_satellite || maptype == AltosMap.maptype_terrain) +			format_string = "jpg"; +		else +			format_string = "png"; +		return new File(AltosPreferences.mapdir(), +				String.format("map-%c%.6f,%c%.6f-%s%d%s.%s", +					      chlat, lat, chlon, lon, maptype_string, zoom, scale == 1 ? "" : String.format("-%d", scale), format_string)); +	} + +	private String map_url() { +		String format_string; +		int z = zoom; + +		if (maptype == AltosMap.maptype_hybrid || maptype == AltosMap.maptype_satellite || maptype == AltosMap.maptype_terrain) +			format_string = "jpg"; +		else +			format_string = "png32"; + +		for (int s = 1; s < scale; s <<= 1) +			z--; + +		if (AltosVersion.has_google_maps_api_key()) +			return String.format("http://maps.google.com/maps/api/staticmap?center=%.6f,%.6f&zoom=%d&size=%dx%d&scale=%d&sensor=false&maptype=%s&format=%s&key=%s", +					     center.lat, center.lon, z, px_size/scale, px_size/scale, scale, AltosMap.maptype_names[maptype], format_string, AltosVersion.google_maps_api_key); +		else +			return String.format("http://maps.google.com/maps/api/staticmap?center=%.6f,%.6f&zoom=%d&size=%dx%d&scale=%d&sensor=false&maptype=%s&format=%s", +					     center.lat, center.lon, z, px_size/scale, px_size/scale, AltosMap.maptype_names[maptype], format_string); +	} + +	public void font_size_changed(int font_size) { +	} + +	public void set_status(int status) { +		this.status = status; +		listener.notify_tile(this, status); +	} + +	public void notify_image(AltosImage image) { +		listener.notify_tile(this, status); +	} + +	public int store_status() { +		return store.status(); +	} + +	public void add_store_listener(AltosMapStoreListener listener) { +		store.add_listener(listener); +	} + +	public void remove_store_listener(AltosMapStoreListener listener) { +		store.remove_listener(listener); +	} + +	public abstract void paint(AltosMapTransform t); + +	public AltosMapTile(AltosMapTileListener listener, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size, int scale) { +		this.listener = listener; +		this.upper_left = upper_left; +		this.cache = listener.cache(); + +		while (center.lon < -180.0) +			center.lon += 360.0; +		while (center.lon > 180.0) +			center.lon -= 360.0; + +		this.center = center; +		this.zoom = zoom; +		this.maptype = maptype; +		this.px_size = px_size; +		this.scale = scale; + +		status = AltosMapTile.loading; +		store = AltosMapStore.get(map_url(), map_file()); +	} + +	public AltosMapTile(AltosMapTileListener listener, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) { +		this(listener, upper_left, center, zoom, maptype, px_size, 1); +	} +} diff --git a/altoslib/AltosMapTileListener.java b/altoslib/AltosMapTileListener.java new file mode 100644 index 00000000..c02483bb --- /dev/null +++ b/altoslib/AltosMapTileListener.java @@ -0,0 +1,24 @@ +/* + * Copyright © 2014 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.altoslib_8; + +public interface AltosMapTileListener { +	abstract public void notify_tile(AltosMapTile tile, int status); + +	abstract public AltosMapCache cache(); +} diff --git a/altoslib/AltosMapTransform.java b/altoslib/AltosMapTransform.java new file mode 100644 index 00000000..b8f29107 --- /dev/null +++ b/altoslib/AltosMapTransform.java @@ -0,0 +1,128 @@ +/* + * Copyright © 2014 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.altoslib_8; + +import java.io.*; +import java.lang.Math; +import java.util.*; +import java.util.concurrent.*; + +public class AltosMapTransform { + +	double	scale_x, scale_y; + +	double	offset_x, offset_y; + +	public AltosLatLon lat_lon (AltosPointDouble point) { +		double lat, lon; +		double rads; + +		lon = point.x/scale_x; +		rads = 2 * Math.atan(Math.exp(-point.y/scale_y)); +		lat = Math.toDegrees(rads - Math.PI/2); + +		return new AltosLatLon(lat,lon); +	} + +	public AltosLatLon lat_lon (AltosPointInt point) { +		return lat_lon(new AltosPointDouble(point.x, point.y)); +	} + +	public AltosPointDouble screen_point(AltosPointInt screen) { +		return new AltosPointDouble(screen.x + offset_x, screen.y + offset_y); +	} + +	public AltosPointDouble screen_point(AltosPointDouble screen) { +		return new AltosPointDouble(screen.x + offset_x, screen.y + offset_y); +	} + +	public double hypot(AltosLatLon a, AltosLatLon b) { +		AltosPointDouble	a_pt = point(a); +		AltosPointDouble	b_pt = point(b); + +		return Math.hypot(a_pt.x - b_pt.x, a_pt.y - b_pt.y); +	} + +	public AltosLatLon screen_lat_lon(AltosPointInt screen) { +		return lat_lon(screen_point(screen)); +	} + +	public AltosLatLon screen_lat_lon(AltosPointDouble screen) { +		return lat_lon(screen_point(screen)); +	} + +	public AltosPointDouble point(AltosLatLon lat_lon) { +		double x, y; +		double e; + +		x = lat_lon.lon * scale_x; + +		e = Math.sin(Math.toRadians(lat_lon.lat)); +		e = Math.max(e,-(1-1.0E-15)); +		e = Math.min(e,  1-1.0E-15 ); + +		y = 0.5*Math.log((1+e)/(1-e))*-scale_y; + +		return new AltosPointDouble(x, y); +	} + +	public AltosPointDouble screen(AltosPointDouble point) { +		return new AltosPointDouble(point.x - offset_x, point.y - offset_y); +	} + +	public AltosPointInt screen(AltosPointInt point) { +		return new AltosPointInt((int) (point.x - offset_x + 0.5), +					 (int) (point.y - offset_y + 0.5)); +	} + +	public AltosRectangle screen(AltosMapRectangle map_rect) { +		AltosPointDouble	ul = screen(map_rect.ul); +		AltosPointDouble	lr = screen(map_rect.lr); + +		return new AltosRectangle((int) ul.x, (int) ul.y, (int) (lr.x - ul.x), (int) (lr.y - ul.y)); +	} + +	public AltosPointDouble screen(AltosLatLon lat_lon) { +		return screen(point(lat_lon)); +	} + +	private boolean has_location; + +	public boolean has_location() { +		return has_location; +	} + +	public AltosMapTransform(int width, int height, int zoom, AltosLatLon centre_lat_lon) { +		scale_x = 256/360.0 * Math.pow(2, zoom); +		scale_y = 256/(2.0*Math.PI) * Math.pow(2, zoom); + +		AltosPointDouble centre_pt = point(centre_lat_lon); + +		has_location = (centre_lat_lon.lat != 0 || centre_lat_lon.lon != 0); +		offset_x = centre_pt.x - width / 2.0; +		offset_y = centre_pt.y - height / 2.0; +	} + +	public static double lon_from_distance(double lat, double distance) { +		double c = AltosGreatCircle.earth_radius * Math.cos(lat * Math.PI / 180) * 2 * Math.PI; + +		if (c < 10) +			return 0; +		return distance/c * 360.0; +	} +} diff --git a/altoslib/AltosMapZoomListener.java b/altoslib/AltosMapZoomListener.java new file mode 100644 index 00000000..aa067303 --- /dev/null +++ b/altoslib/AltosMapZoomListener.java @@ -0,0 +1,22 @@ +/* + * Copyright © 2014 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.altoslib_8; + +public interface AltosMapZoomListener { +	abstract public void zoom_changed(int zoom); +} diff --git a/altoslib/AltosMma655x.java b/altoslib/AltosMma655x.java index c0b94b8c..8b1ac088 100644 --- a/altoslib/AltosMma655x.java +++ b/altoslib/AltosMma655x.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.util.concurrent.*; diff --git a/altoslib/AltosMs5607.java b/altoslib/AltosMs5607.java index 2bd4ba8f..e7ca1ba3 100644 --- a/altoslib/AltosMs5607.java +++ b/altoslib/AltosMs5607.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.util.concurrent.*;  import java.io.*; diff --git a/altoslib/AltosNoSymbol.java b/altoslib/AltosNoSymbol.java index 77410a25..6ef2a142 100644 --- a/altoslib/AltosNoSymbol.java +++ b/altoslib/AltosNoSymbol.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public class AltosNoSymbol extends Exception {  	public AltosNoSymbol(String name) { diff --git a/altoslib/AltosOrient.java b/altoslib/AltosOrient.java index 8cdde750..1c2e2aab 100644 --- a/altoslib/AltosOrient.java +++ b/altoslib/AltosOrient.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public class AltosOrient extends AltosUnits { diff --git a/altoslib/AltosParse.java b/altoslib/AltosParse.java index 2fb69c15..8f624b96 100644 --- a/altoslib/AltosParse.java +++ b/altoslib/AltosParse.java @@ -15,8 +15,9 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8; +import java.util.*;  import java.text.*;  public class AltosParse { @@ -40,11 +41,23 @@ public class AltosParse {  		}  	} -	public static double parse_double(String v) throws ParseException { +	static NumberFormat nf_locale = NumberFormat.getInstance(); + +	static NumberFormat nf_net = NumberFormat.getInstance(Locale.ROOT); + +	public static double parse_double_locale(String str) throws ParseException {  		try { -			return Double.parseDouble(v); -		} catch (NumberFormatException e) { -			throw new ParseException("error parsing double " + v, 0); +			return nf_locale.parse(str.trim()).doubleValue(); +		} catch (ParseException pe) { +			throw new ParseException("error parsing double " + str, 0); +		} +	} + +	public static double parse_double_net(String str) throws ParseException { +		try { +			return nf_net.parse(str.trim()).doubleValue(); +		} catch (ParseException pe) { +			throw new ParseException("error parsing double " + str, 0);  		}  	} diff --git a/altoslib/AltosPointDouble.java b/altoslib/AltosPointDouble.java new file mode 100644 index 00000000..ecfcbea7 --- /dev/null +++ b/altoslib/AltosPointDouble.java @@ -0,0 +1,53 @@ +/* + * 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.altoslib_8; + +public class AltosPointDouble { +	public double	x, y; + +	public int hashCode() { +		return new Double(x).hashCode() ^ new Double(y).hashCode(); +	} + +	public boolean equals(Object o) { +		if (o == null) +			return false; + +		if (!(o instanceof AltosPointDouble)) +			return false; + +		AltosPointDouble n = (AltosPointDouble) o; + +		return n.x == x && n.y == y; +	} + +	public AltosPointDouble(double x, double y) { +		this.x = x; +		this.y = y; +	} + +	public AltosPointDouble(int x, int y) { +		this.x = x; +		this.y = y; +	} + +	public AltosPointDouble(AltosPointInt p) { +		this.x = p.x; +		this.y = p.y; +	} +} diff --git a/altoslib/AltosPointInt.java b/altoslib/AltosPointInt.java new file mode 100644 index 00000000..e690aa43 --- /dev/null +++ b/altoslib/AltosPointInt.java @@ -0,0 +1,53 @@ +/* + * 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.altoslib_8; + +public class AltosPointInt { +	public int	x, y; + +	public int hashCode() { +		return  x ^ y; +	} + +	public boolean equals(Object o) { +		if (o == null) +			return false; + +		if (!(o instanceof AltosPointInt)) +			return false; + +		AltosPointInt n = (AltosPointInt) o; + +		return n.x == x && n.y == y; +	} + +	public AltosPointInt(int x, int y) { +		this.x = x; +		this.y = y; +	} + +	public AltosPointInt(double x, double y) { +		this.x = (int) (x + 0.5); +		this.y = (int) (y + 0.5); +	} + +	public AltosPointInt(AltosPointDouble pt_d) { +		this.x = (int) (pt_d.x + 0.5); +		this.y = (int) (pt_d.y + 0.5); +	} +} diff --git a/altoslib/AltosPreferences.java b/altoslib/AltosPreferences.java index 5aa45d3f..a1e76834 100644 --- a/altoslib/AltosPreferences.java +++ b/altoslib/AltosPreferences.java @@ -15,10 +15,11 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*;  import java.util.*; +import java.text.*;  public class AltosPreferences {  	public static AltosPreferencesBackend backend = null; @@ -42,7 +43,9 @@ public class AltosPreferences {  	public final static String logfilePreferenceFormat = "LOGFILE-%d";  	/* state preference name */ +	public final static String statePreferenceHead = "STATE-";  	public final static String statePreferenceFormat = "STATE-%d"; +	public final static String statePreferenceLatest = "STATE-LATEST";  	/* voice preference name */  	public final static String voicePreference = "VOICE"; @@ -118,6 +121,13 @@ public class AltosPreferences {  	public final static String	unitsPreference = "IMPERIAL-UNITS"; +	/* Maps cache size preference name */ +	final static String mapCachePreference = "MAP-CACHE"; + +	static LinkedList<AltosMapCacheListener> map_cache_listeners; + +	public static int map_cache = 9; +  	public static AltosFrequency[] load_common_frequencies() {  		AltosFrequency[] frequencies = null;  		boolean	existing = false; @@ -208,6 +218,9 @@ public class AltosPreferences {  		common_frequencies = load_common_frequencies();  		AltosConvert.imperial_units = backend.getBoolean(unitsPreference, false); + +		map_cache = backend.getInt(mapCachePreference, 9); +		map_cache_listeners = new LinkedList<AltosMapCacheListener>();  	}  	public static void flush_preferences() { @@ -350,12 +363,43 @@ public class AltosPreferences {  			synchronized(backend) {  				backend.putBytes(String.format(statePreferenceFormat, serial), bytes); +				backend.putInt(statePreferenceLatest, serial);  				flush_preferences();  			}  		} catch (IOException ie) {  		}  	} +	public static ArrayList<Integer> list_states() { +		String[]		keys = backend.keys(); +		ArrayList<Integer>	states = new ArrayList<Integer>(); + +		for (String key : keys) { +			if (key.startsWith(statePreferenceHead)) { +				try { +					int serial = AltosParse.parse_int(key.substring(statePreferenceHead.length())); +					states.add(serial); +				} catch (ParseException pe) { +				} +			} +		} +		return states; +	} + +	public static void remove_state(int serial) { +		synchronized(backend) { +			backend.remove(String.format(statePreferenceFormat, serial)); +		} +	} + +	public static int latest_state() { +		int	latest = 0; +		synchronized (backend) { +			latest = backend.getInt(statePreferenceLatest, 0); +		} +		return latest; +	} +  	public static AltosSavedState state(int serial) {  		byte[] bytes = null; @@ -548,4 +592,33 @@ public class AltosPreferences {  			units_listeners.remove(l);  		}  	} + + +	public static void register_map_cache_listener(AltosMapCacheListener l) { +		synchronized(backend) { +			map_cache_listeners.add(l); +		} +	} + +	public static void unregister_map_cache_listener(AltosMapCacheListener l) { +		synchronized (backend) { +			map_cache_listeners.remove(l); +		} +	} + +	public static void set_map_cache(int new_map_cache) { +		synchronized(backend) { +			map_cache = new_map_cache; +			backend.putInt(mapCachePreference, map_cache); +			flush_preferences(); +			for (AltosMapCacheListener l: map_cache_listeners) +				l.map_cache_changed(map_cache); +		} +	} + +	public static int map_cache() { +		synchronized(backend) { +			return map_cache; +		} +	}  } diff --git a/altoslib/AltosPreferencesBackend.java b/altoslib/AltosPreferencesBackend.java index c83eaa47..3154a519 100644 --- a/altoslib/AltosPreferencesBackend.java +++ b/altoslib/AltosPreferencesBackend.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.File; diff --git a/altoslib/AltosProgrammer.java b/altoslib/AltosProgrammer.java index 7a92c2d0..74ab42b5 100644 --- a/altoslib/AltosProgrammer.java +++ b/altoslib/AltosProgrammer.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*; diff --git a/altoslib/AltosPyro.java b/altoslib/AltosPyro.java index 502e34de..9b7e79f3 100644 --- a/altoslib/AltosPyro.java +++ b/altoslib/AltosPyro.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.util.*;  import java.text.*; diff --git a/altoslib/AltosQuaternion.java b/altoslib/AltosQuaternion.java index 4ad1f3d6..f78b5065 100644 --- a/altoslib/AltosQuaternion.java +++ b/altoslib/AltosQuaternion.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public class AltosQuaternion {  	double	r;		/* real bit */ diff --git a/altoslib/AltosRectangle.java b/altoslib/AltosRectangle.java new file mode 100644 index 00000000..1b1cc9f4 --- /dev/null +++ b/altoslib/AltosRectangle.java @@ -0,0 +1,29 @@ +/* + * 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.altoslib_8; + +public class AltosRectangle { +	public int	x, y, width, height; + +	public AltosRectangle(int x, int y, int w, int h) { +		this.x = x; +		this.y = y; +		this.width = w; +		this.height = h; +	} +} diff --git a/altoslib/AltosReplayReader.java b/altoslib/AltosReplayReader.java index 98f0e7d5..9419ec93 100644 --- a/altoslib/AltosReplayReader.java +++ b/altoslib/AltosReplayReader.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*;  import java.util.*; @@ -40,7 +40,7 @@ public class AltosReplayReader extends AltosFlightReader {  	public void update(AltosState state) throws InterruptedException {  		/* Make it run in realtime after the rocket leaves the pad */  		if (state.state > AltosLib.ao_flight_pad && state.time_change > 0) -			Thread.sleep((int) (Math.min(state.time_change,10) * 100)); +			Thread.sleep((int) (Math.min(state.time_change,10) * 1000));  		state.set_received_time(System.currentTimeMillis());  	} diff --git a/altoslib/AltosRomconfig.java b/altoslib/AltosRomconfig.java index c93a01c3..28134aeb 100644 --- a/altoslib/AltosRomconfig.java +++ b/altoslib/AltosRomconfig.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*; diff --git a/altoslib/AltosRotation.java b/altoslib/AltosRotation.java index 49225f77..9771c166 100644 --- a/altoslib/AltosRotation.java +++ b/altoslib/AltosRotation.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public class AltosRotation {  	private AltosQuaternion		rotation; diff --git a/altoslib/AltosSavedState.java b/altoslib/AltosSavedState.java index 552e4533..e2ca9f73 100644 --- a/altoslib/AltosSavedState.java +++ b/altoslib/AltosSavedState.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*; diff --git a/altoslib/AltosSelfFlash.java b/altoslib/AltosSelfFlash.java index 83be4be1..e2988b56 100644 --- a/altoslib/AltosSelfFlash.java +++ b/altoslib/AltosSelfFlash.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*; diff --git a/altoslib/AltosSensorEMini.java b/altoslib/AltosSensorEMini.java index cb8356a1..e8b7b044 100644 --- a/altoslib/AltosSensorEMini.java +++ b/altoslib/AltosSensorEMini.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.util.concurrent.TimeoutException; diff --git a/altoslib/AltosSensorMM.java b/altoslib/AltosSensorMM.java index 9d5649aa..9be29ae0 100644 --- a/altoslib/AltosSensorMM.java +++ b/altoslib/AltosSensorMM.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.util.concurrent.TimeoutException; diff --git a/altoslib/AltosSensorMega.java b/altoslib/AltosSensorMega.java index a3c2a033..1f71302e 100644 --- a/altoslib/AltosSensorMega.java +++ b/altoslib/AltosSensorMega.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.util.concurrent.TimeoutException; diff --git a/altoslib/AltosSensorMetrum.java b/altoslib/AltosSensorMetrum.java index 39592b50..c00e00d5 100644 --- a/altoslib/AltosSensorMetrum.java +++ b/altoslib/AltosSensorMetrum.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.util.concurrent.TimeoutException; diff --git a/altoslib/AltosSensorTGPS.java b/altoslib/AltosSensorTGPS.java index 32607fba..64cce640 100644 --- a/altoslib/AltosSensorTGPS.java +++ b/altoslib/AltosSensorTGPS.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.util.concurrent.TimeoutException; diff --git a/altoslib/AltosSensorTM.java b/altoslib/AltosSensorTM.java index c82ba93c..4957b94d 100644 --- a/altoslib/AltosSensorTM.java +++ b/altoslib/AltosSensorTM.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.util.concurrent.TimeoutException; diff --git a/altoslib/AltosSensorTMini.java b/altoslib/AltosSensorTMini.java index 0fc70e71..9b2db2ff 100644 --- a/altoslib/AltosSensorTMini.java +++ b/altoslib/AltosSensorTMini.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.util.concurrent.TimeoutException; diff --git a/altoslib/AltosSpeed.java b/altoslib/AltosSpeed.java index b714412f..b9fca82b 100644 --- a/altoslib/AltosSpeed.java +++ b/altoslib/AltosSpeed.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public class AltosSpeed extends AltosUnits { diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index d363027c..4edae54a 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -19,7 +19,7 @@   * Track flight state from telemetry or eeprom data stream   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*; @@ -31,8 +31,9 @@ public class AltosState implements Cloneable, Serializable {  	public int set; +	static final double filter_len = 2.0;  	static final double ascent_filter_len = 0.5; -	static final double descent_filter_len = 0.5; +	static final double descent_filter_len = 5.0;  	/* derived data */ @@ -64,8 +65,10 @@ public class AltosState implements Cloneable, Serializable {  		}  		void set_filtered(double new_value, double time) { -			if (prev_value != AltosLib.MISSING) -				new_value = (prev_value * 15.0 + new_value) / 16.0; +			if (prev_value != AltosLib.MISSING) { +				double f = 1/Math.exp((time - prev_set_time) / filter_len); +				new_value = f * new_value + (1-f) * prev_value; +			}  			set(new_value, time);  		} @@ -1040,6 +1043,10 @@ public class AltosState implements Cloneable, Serializable {  		return AltosLib.state_name(state);  	} +	public void set_product(String product) { +		this.product = product; +	} +  	public void set_state(int state) {  		if (state != AltosLib.ao_flight_invalid) {  			this.state = state; diff --git a/altoslib/AltosStateIterable.java b/altoslib/AltosStateIterable.java index 3b58fc32..5533468b 100644 --- a/altoslib/AltosStateIterable.java +++ b/altoslib/AltosStateIterable.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*;  import java.util.*; diff --git a/altoslib/AltosStateUpdate.java b/altoslib/AltosStateUpdate.java index 93b9f1c0..ed2e1826 100644 --- a/altoslib/AltosStateUpdate.java +++ b/altoslib/AltosStateUpdate.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public interface AltosStateUpdate {  	public void	update_state(AltosState state) throws InterruptedException; diff --git a/altoslib/AltosTelemetry.java b/altoslib/AltosTelemetry.java index 449384d5..4c973cd9 100644 --- a/altoslib/AltosTelemetry.java +++ b/altoslib/AltosTelemetry.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.text.*; diff --git a/altoslib/AltosTelemetryConfiguration.java b/altoslib/AltosTelemetryConfiguration.java index 8c922b03..c4cd36b2 100644 --- a/altoslib/AltosTelemetryConfiguration.java +++ b/altoslib/AltosTelemetryConfiguration.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public class AltosTelemetryConfiguration extends AltosTelemetryStandard { diff --git a/altoslib/AltosTelemetryFile.java b/altoslib/AltosTelemetryFile.java index 738e4dd7..d2275f54 100644 --- a/altoslib/AltosTelemetryFile.java +++ b/altoslib/AltosTelemetryFile.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*;  import java.util.*; diff --git a/altoslib/AltosTelemetryIterable.java b/altoslib/AltosTelemetryIterable.java index 131389d5..e18f7eda 100644 --- a/altoslib/AltosTelemetryIterable.java +++ b/altoslib/AltosTelemetryIterable.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.io.*;  import java.util.*; diff --git a/altoslib/AltosTelemetryLegacy.java b/altoslib/AltosTelemetryLegacy.java index 923d139e..f8e72c86 100644 --- a/altoslib/AltosTelemetryLegacy.java +++ b/altoslib/AltosTelemetryLegacy.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.text.*; diff --git a/altoslib/AltosTelemetryLocation.java b/altoslib/AltosTelemetryLocation.java index 85da27d5..9341d003 100644 --- a/altoslib/AltosTelemetryLocation.java +++ b/altoslib/AltosTelemetryLocation.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public class AltosTelemetryLocation extends AltosTelemetryStandard { diff --git a/altoslib/AltosTelemetryMap.java b/altoslib/AltosTelemetryMap.java index e8c02e9b..d3242254 100644 --- a/altoslib/AltosTelemetryMap.java +++ b/altoslib/AltosTelemetryMap.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.text.*;  import java.util.HashMap; diff --git a/altoslib/AltosTelemetryMegaData.java b/altoslib/AltosTelemetryMegaData.java index 2b80df4a..2af8d931 100644 --- a/altoslib/AltosTelemetryMegaData.java +++ b/altoslib/AltosTelemetryMegaData.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public class AltosTelemetryMegaData extends AltosTelemetryStandard {  	int	state; diff --git a/altoslib/AltosTelemetryMegaSensor.java b/altoslib/AltosTelemetryMegaSensor.java index a01c0826..77a76cd7 100644 --- a/altoslib/AltosTelemetryMegaSensor.java +++ b/altoslib/AltosTelemetryMegaSensor.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public class AltosTelemetryMegaSensor extends AltosTelemetryStandard {  	int	accel; diff --git a/altoslib/AltosTelemetryMetrumData.java b/altoslib/AltosTelemetryMetrumData.java index e53f1283..17a3410a 100644 --- a/altoslib/AltosTelemetryMetrumData.java +++ b/altoslib/AltosTelemetryMetrumData.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public class AltosTelemetryMetrumData extends AltosTelemetryStandard { diff --git a/altoslib/AltosTelemetryMetrumSensor.java b/altoslib/AltosTelemetryMetrumSensor.java index 415b00a6..71fbd544 100644 --- a/altoslib/AltosTelemetryMetrumSensor.java +++ b/altoslib/AltosTelemetryMetrumSensor.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public class AltosTelemetryMetrumSensor extends AltosTelemetryStandard { diff --git a/altoslib/AltosTelemetryMini.java b/altoslib/AltosTelemetryMini.java index 02537c9c..c9fda5b8 100644 --- a/altoslib/AltosTelemetryMini.java +++ b/altoslib/AltosTelemetryMini.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public class AltosTelemetryMini extends AltosTelemetryStandard { diff --git a/altoslib/AltosTelemetryRaw.java b/altoslib/AltosTelemetryRaw.java index 4254fc83..843ca4eb 100644 --- a/altoslib/AltosTelemetryRaw.java +++ b/altoslib/AltosTelemetryRaw.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public class AltosTelemetryRaw extends AltosTelemetryStandard {  	public AltosTelemetryRaw(int[] bytes) { diff --git a/altoslib/AltosTelemetryReader.java b/altoslib/AltosTelemetryReader.java index 908fb5c7..cbbdceff 100644 --- a/altoslib/AltosTelemetryReader.java +++ b/altoslib/AltosTelemetryReader.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  import java.text.*;  import java.io.*; diff --git a/altoslib/AltosTelemetrySatellite.java b/altoslib/AltosTelemetrySatellite.java index 474789ba..2f4e3354 100644 --- a/altoslib/AltosTelemetrySatellite.java +++ b/altoslib/AltosTelemetrySatellite.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public class AltosTelemetrySatellite extends AltosTelemetryStandard {  	int		channels; diff --git a/altoslib/AltosTelemetrySensor.java b/altoslib/AltosTelemetrySensor.java index b0c84fd3..27cf22f0 100644 --- a/altoslib/AltosTelemetrySensor.java +++ b/altoslib/AltosTelemetrySensor.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public class AltosTelemetrySensor extends AltosTelemetryStandard { diff --git a/altoslib/AltosTelemetryStandard.java b/altoslib/AltosTelemetryStandard.java index fb8a162e..27561826 100644 --- a/altoslib/AltosTelemetryStandard.java +++ b/altoslib/AltosTelemetryStandard.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public abstract class AltosTelemetryStandard extends AltosTelemetry {  	int[]	bytes; diff --git a/altoslib/AltosTemperature.java b/altoslib/AltosTemperature.java index 494f4e3e..b4d465a0 100644 --- a/altoslib/AltosTemperature.java +++ b/altoslib/AltosTemperature.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public class AltosTemperature extends AltosUnits { diff --git a/altoslib/AltosUnits.java b/altoslib/AltosUnits.java index f6e34e77..6b4fff0c 100644 --- a/altoslib/AltosUnits.java +++ b/altoslib/AltosUnits.java @@ -15,7 +15,9 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8; + +import java.text.*;  public abstract class AltosUnits { @@ -29,13 +31,22 @@ public abstract class AltosUnits {  	public abstract int show_fraction(int width, boolean imperial_units); -	public double parse(String s, boolean imperial_units) throws NumberFormatException { -		double v = Double.parseDouble(s); +	public double parse_locale(String s, boolean imperial_units) throws ParseException { +		double v = AltosParse.parse_double_locale(s); +		return inverse(v, imperial_units); +	} + +	public double parse_net(String s, boolean imperial_units) throws ParseException { +		double v = AltosParse.parse_double_net(s);  		return inverse(v, imperial_units);  	} -	public double parse(String s) throws NumberFormatException { -		return parse(s, AltosConvert.imperial_units); +	public double parse_locale(String s) throws ParseException { +		return parse_locale(s, AltosConvert.imperial_units); +	} + +	public double parse_net(String s) throws ParseException { +		return parse_net(s, AltosConvert.imperial_units);  	}  	public double value(double v) { @@ -105,4 +116,4 @@ public abstract class AltosUnits {  	public String say_units(double v) {  		return say_units(v, AltosConvert.imperial_units);  	} -}
\ No newline at end of file +} diff --git a/altoslib/AltosUnitsListener.java b/altoslib/AltosUnitsListener.java index 1b66eb45..0e31492e 100644 --- a/altoslib/AltosUnitsListener.java +++ b/altoslib/AltosUnitsListener.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public interface AltosUnitsListener {  	public void units_changed(boolean imperial_units); diff --git a/altoslib/AltosVersion.java.in b/altoslib/AltosVersion.java.in new file mode 100644 index 00000000..89ed400f --- /dev/null +++ b/altoslib/AltosVersion.java.in @@ -0,0 +1,28 @@ +/* + * Copyright © 2011 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.altoslib_8; + +public class AltosVersion { +	public final static String version = "@VERSION@"; + +	public final static String google_maps_api_key = @GOOGLEKEY@; + +	public static boolean has_google_maps_api_key() { +		return google_maps_api_key != null && google_maps_api_key.length() > 1; +	} +} diff --git a/altoslib/AltosVoltage.java b/altoslib/AltosVoltage.java index 986d74b4..fb6f41ee 100644 --- a/altoslib/AltosVoltage.java +++ b/altoslib/AltosVoltage.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public class AltosVoltage extends AltosUnits { diff --git a/altoslib/AltosWriter.java b/altoslib/AltosWriter.java index b125bd87..1dcd3391 100644 --- a/altoslib/AltosWriter.java +++ b/altoslib/AltosWriter.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_6; +package org.altusmetrum.altoslib_8;  public interface AltosWriter { diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index c640c69c..a6b178fa 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -128,7 +128,35 @@ altoslib_JAVA = \  	AltosPyro.java \  	AltosWriter.java \  	AltosQuaternion.java \ -	AltosRotation.java +	AltosRotation.java \ +	AltosImage.java \ +	AltosLatLon.java \ +	AltosMap.java \ +	AltosMapCache.java \ +	AltosMapCacheListener.java \ +	AltosMapInterface.java \ +	AltosMapLine.java \ +	AltosMapMark.java \ +	AltosMapPath.java \ +	AltosMapPathPoint.java \ +	AltosMapRectangle.java \ +	AltosMapStore.java \ +	AltosMapStoreListener.java \ +	AltosMapTile.java \ +	AltosMapTileListener.java \ +	AltosMapTransform.java \ +	AltosMapZoomListener.java \ +	AltosPointDouble.java \ +	AltosPointInt.java \ +	AltosRectangle.java \ +	AltosFlightDisplay.java \ +	AltosFontListener.java \ +	AltosLaunchSite.java \ +	AltosLaunchSiteListener.java \ +	AltosLaunchSites.java \ +	AltosMapLoaderListener.java \ +	AltosMapLoader.java \ +	AltosVersion.java  JAR=altoslib_$(ALTOSLIB_VERSION).jar  | 
