aboutsummaryrefslogtreecommitdiff
path: root/engine/src/desktop/jme3tools/navigation/Coordinate.java
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src/desktop/jme3tools/navigation/Coordinate.java')
-rw-r--r--engine/src/desktop/jme3tools/navigation/Coordinate.java247
1 files changed, 247 insertions, 0 deletions
diff --git a/engine/src/desktop/jme3tools/navigation/Coordinate.java b/engine/src/desktop/jme3tools/navigation/Coordinate.java
new file mode 100644
index 0000000..6e2c2d2
--- /dev/null
+++ b/engine/src/desktop/jme3tools/navigation/Coordinate.java
@@ -0,0 +1,247 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package jme3tools.navigation;
+
+import java.text.DecimalFormat;
+
+/**
+ * Coordinate class. Used to store a coordinate in [DD]D MM.M format.
+ *
+ * @author Benjamin Jakobus (based on JMarine by Benjamin Jakobus and Cormac Gebruers)
+ * @version 1.0
+ * @since 1.0
+ */
+public class Coordinate {
+
+ /* the degree part of the position (+ N/E, -W/S) */
+ private int deg;
+
+ /* the decimals of a minute */
+ private double minsDecMins;
+
+ /* the coordinate as a decimal*/
+ private double decCoordinate;
+
+ /* whether this coordinate is a latitude or a longitude: : LAT==0, LONG==1 */
+ private int coOrdinate;
+
+ /* The minutes trailing decimal precision to use for positions */
+ public static final int MINPRECISION = 4;
+ /* The degrees trailing decimal precision to use for positions */
+ public static final int DEGPRECISION = 7;
+
+ /* typeDefs for coOrdinates */
+ public static final int LAT = 0;
+ public static final int LNG = 1;
+
+ /* typeDefs for quadrant */
+ public static final int E = 0;
+ public static final int S = 1;
+ public static final int W = 2;
+ public static final int N = 3;
+
+ /**
+ * Constructor
+ *
+ * @param deg
+ * @param minsDecMins
+ * @param coOrdinate
+ * @param quad
+ * @throws InvalidPositionException
+ * @since 1.0
+ */
+ public Coordinate(int deg, float minsDecMins, int coOrdinate,
+ int quad) throws InvalidPositionException {
+ buildCoOrdinate(deg, minsDecMins, coOrdinate, quad);
+ if (verify()) {
+ } else {
+ throw new InvalidPositionException();
+ }
+ }
+
+ /**
+ * Constructor
+ * @param decCoordinate
+ * @param coOrdinate
+ * @throws InvalidPositionException
+ * @since 1.0
+ */
+ public Coordinate(double decCoordinate, int coOrdinate) throws InvalidPositionException {
+ DecimalFormat form = new DecimalFormat("#.#######");
+
+ this.decCoordinate = decCoordinate;
+ this.coOrdinate = coOrdinate;
+ if (verify()) {
+ deg = new Float(decCoordinate).intValue();
+ if (deg < 0) {
+ minsDecMins = Double.parseDouble(form.format((Math.abs(decCoordinate) - Math.abs(deg)) * 60));
+ } else {
+ minsDecMins = Double.parseDouble(form.format((decCoordinate - deg) * 60));
+ }
+ } else {
+ throw new InvalidPositionException();
+ }
+ }
+
+ /**
+ * This constructor takes a coordinate in the ALRS formats i.e
+ * 38∞31.64'N for lat, and 28∞19.12'W for long
+ * Note: ALRS positions are occasionally written with the decimal minutes
+ * apostrophe in the 'wrong' place and with an non CP1252 compliant decimal character.
+ * This issue has to be corrected in the source database
+ * @param coOrdinate
+ * @throws InvalidPositionException
+ * @since 1.0
+ */
+ public Coordinate(String coOrdinate) throws InvalidPositionException {
+ //firstly split it into its component parts and dispose of the unneeded characters
+ String[] items = coOrdinate.split("°");
+ int deg = Integer.valueOf(items[0]);
+
+ items = items[1].split("'");
+ float minsDecMins = Float.valueOf(items[0]);
+ char quad = items[1].charAt(0);
+
+ switch (quad) {
+ case 'N':
+ buildCoOrdinate(deg, minsDecMins, Coordinate.LAT, Coordinate.N);
+ break;
+ case 'S':
+ buildCoOrdinate(deg, minsDecMins, Coordinate.LAT, Coordinate.S);
+ break;
+ case 'E':
+ buildCoOrdinate(deg, minsDecMins, Coordinate.LNG, Coordinate.E);
+ break;
+ case 'W':
+ buildCoOrdinate(deg, minsDecMins, Coordinate.LNG, Coordinate.W);
+ }
+ if (verify()) {
+ } else {
+ throw new InvalidPositionException();
+ }
+ }
+
+ /**
+ * Prints out a coordinate as a string
+ * @return the coordinate in decimal format
+ * @since 1.0
+ */
+ public String toStringDegMin() {
+ String str = "";
+ String quad = "";
+ StringUtil su = new StringUtil();
+ switch (coOrdinate) {
+ case LAT:
+ if (decCoordinate >= 0) {
+ quad = "N";
+ } else {
+ quad = "S";
+ }
+ str = su.padNumZero(Math.abs(deg), 2);
+ str += "\u00b0" + su.padNumZero(Math.abs(minsDecMins), 2, MINPRECISION) + "'" + quad;
+ break;
+ case LNG:
+ if (decCoordinate >= 0) {
+ quad = "E";
+ } else {
+ quad = "W";
+ }
+ str = su.padNumZero(Math.abs(deg), 3);
+ str += "\u00b0" + su.padNumZero(Math.abs(minsDecMins), 2, MINPRECISION) + "'" + quad;
+ break;
+ }
+ return str;
+ }
+
+ /**
+ * Prints out a coordinate as a string
+ * @return the coordinate in decimal format
+ * @since 1.0
+ */
+ public String toStringDec() {
+ StringUtil u = new StringUtil();
+ switch (coOrdinate) {
+ case LAT:
+ return u.padNumZero(decCoordinate, 2, DEGPRECISION);
+ case LNG:
+ return u.padNumZero(decCoordinate, 3, DEGPRECISION);
+ }
+ return "error";
+ }
+
+ /**
+ * Returns the coordinate's decimal value
+ * @return float the decimal value of the coordinate
+ * @since 1.0
+ */
+ public double decVal() {
+ return decCoordinate;
+ }
+
+ /**
+ * Determines whether a decimal position is valid
+ * @return result of validity test
+ * @since 1.0
+ */
+ private boolean verify() {
+ switch (coOrdinate) {
+ case LAT:
+ if (Math.abs(decCoordinate) > 90.0) {
+ return false;
+ }
+ break;
+
+ case LNG:
+ if (Math.abs(decCoordinate) > 180) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Populate this object by parsing the arguments to the function
+ * Placed here to allow multiple constructors to use it
+ * @since 1.0
+ */
+ private void buildCoOrdinate(int deg, float minsDecMins, int coOrdinate,
+ int quad) {
+ NumUtil nu = new NumUtil();
+
+ switch (coOrdinate) {
+ case LAT:
+ switch (quad) {
+ case N:
+ this.deg = deg;
+ this.minsDecMins = minsDecMins;
+ this.coOrdinate = coOrdinate;
+ decCoordinate = nu.Round(this.deg + (float) this.minsDecMins / 60, Coordinate.MINPRECISION);
+ break;
+
+ case S:
+ this.deg = -deg;
+ this.minsDecMins = minsDecMins;
+ this.coOrdinate = coOrdinate;
+ decCoordinate = nu.Round(this.deg - ((float) this.minsDecMins / 60), Coordinate.MINPRECISION);
+ }
+
+ case LNG:
+ switch (quad) {
+ case E:
+ this.deg = deg;
+ this.minsDecMins = minsDecMins;
+ this.coOrdinate = coOrdinate;
+ decCoordinate = nu.Round(this.deg + ((float) this.minsDecMins / 60), Coordinate.MINPRECISION);
+ break;
+
+ case W:
+ this.deg = -deg;
+ this.minsDecMins = minsDecMins;
+ this.coOrdinate = coOrdinate;
+ decCoordinate = nu.Round(this.deg - ((float) this.minsDecMins / 60), Coordinate.MINPRECISION);
+ }
+ }
+ }
+}