Package nav.position

Source Code of nav.position.Coordinate

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package nav.position;

import exception.InvalidPositionException;
import java.text.DecimalFormat;
import nav.util.string.StringUtil;
import nav.util.math.NumUtil;

/**
* Coordinate class. Used to store a coordinate in [DD]D MM.M format.
*
* @author Benjamin Jakobus
* @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;

    /* Type definitions for coordinates. */
    public static final int LAT = 0;
    public static final int LNG = 1;

    /* Type definitions for the 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               Degrees.
     * @param minsDecMins       Minutes.
     * @param coordinate        Coordinate type (latitude or longitude).
     * @param quad              Quadrant.
     *
     * @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     Coordinate in decimal format.
     * @param coordinate        Coordinate type (latitude or longitude).
     * @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                Coordinate as a <code>String</code>.
     * @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();
        }
    }

    /**
     * Returns the coordinate as a <code>String</code> in degrees and minutes.
     *
     * @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;
        }
        return str;
    }

    /**
     * Returns the coordinate as a <code>String</code> in decimal format.
     *
     * @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; <code>true</code>
     *                              if valid; <code>false</code> if not.
     * @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);
                }
        }
    }
}
TOP

Related Classes of nav.position.Coordinate

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.