如何在java中将os网格引用转换为经度和纬度?

时间:2016-04-05 10:37:38

标签: java android

我希望将OS Grid Reference转换为经度和纬度,我在Android studio中使用jcoord库,http://www.jstott.me.uk/jcoord/

我很感兴趣如何将此连接到一个按钮,您可以在活动中输入编辑文本的网格参考,然后单击转换(这将执行神奇公式)并将显示下面的经度和纬度?

基本上我想创建一个用户界面,能够在我的手机上测试它

我相信公式将在OSRef.java中完成,代码如下:

public class OSRef extends Activity implements View.OnClickListener {

EditText osGridNumber;
View convertButton;
TextView latLongBox;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    convertButton = findViewById(R.id.cmdConvert);
    convertButton.setOnClickListener(this);

    osGridNumber = (EditText) findViewById(R.id.edtOS);

    latLongBox = (TextView) findViewById(R.id.txtLngLat);

}


@Override
public void onClick(View v) {
    switch (v.getId()) {

        case R.id.cmdConvert:

            break;
    }
}

/**
 * Easting
 */
private double easting;

/**
 * Northing
 */
private double northing;


/**
 * Create a new Ordnance Survey grid reference.
 *
 * @param easting  the easting in metres
 * @param northing the northing in metres
 * @since 1.0
 */
public OSRef(double easting, double northing) {
    this.easting = easting;
    this.northing = northing;
}


/**
 * Take a string formatted as a six-figure OS grid reference (e.g. "TG514131")
 * and create a new OSRef object that represents that grid reference. The
 * first character must be H, N, S, O or T. The second character can be any
 * uppercase character from A through Z excluding I.
 *
 * @param ref a String representing a six-figure Ordnance Survey grid reference
 *            in the form XY123456
 * @throws IllegalArgumentException if ref is not of the form XY123456
 * @since 1.0
 */
public OSRef(String ref) throws IllegalArgumentException {
    // if (ref.matches(""))
    char char1 = ref.charAt(0);
    char char2 = ref.charAt(1);
    // Thanks to Nick Holloway for pointing out the radix bug here
    int east = Integer.parseInt(ref.substring(2, 5)) * 100;
    int north = Integer.parseInt(ref.substring(5, 8)) * 100;
    if (char1 == 'H') {
        north += 1000000;
    } else if (char1 == 'N') {
        north += 500000;
    } else if (char1 == 'O') {
        north += 500000;
        east += 500000;
    } else if (char1 == 'T') {
        east += 500000;
    }
    int char2ord = char2;
    if (char2ord > 73)
        char2ord--; // Adjust for no I
    double nx = ((char2ord - 65) % 5) * 100000;
    double ny = (4 - Math.floor((char2ord - 65) / 5)) * 100000;
    easting = east + nx;
    northing = north + ny;
}


/**
 * Return a String representation of this OSGB grid reference showing the
 * easting and northing.
 *
 * @return a String represenation of this OSGB grid reference
 * @since 1.0
 */
public String toString() {
    return "(" + easting + ", " + northing + ")";
}


/**
 * Return a String representation of this OSGB grid reference using the
 * six-figure notation in the form XY123456
 *
 * @return a String representing this OSGB grid reference in six-figure
 * notation
 * @since 1.0
 */
public String toSixFigureString() {
    int hundredkmE = (int) Math.floor(easting / 100000);
    int hundredkmN = (int) Math.floor(northing / 100000);
    String firstLetter;
    if (hundredkmN < 5) {
        if (hundredkmE < 5) {
            firstLetter = "S";
        } else {
            firstLetter = "T";
        }
    } else if (hundredkmN < 10) {
        if (hundredkmE < 5) {
            firstLetter = "N";
        } else {
            firstLetter = "O";
        }
    } else {
        firstLetter = "H";
    }

    int index = 65 + ((4 - (hundredkmN % 5)) * 5) + (hundredkmE % 5);
    // int ti = index;
    if (index >= 73)
        index++;
    String secondLetter = Character.toString((char) index);

    int e = (int) Math.floor((easting - (100000 * hundredkmE)) / 100);
    int n = (int) Math.floor((northing - (100000 * hundredkmN)) / 100);
    String es = "" + e;
    if (e < 100)
        es = "0" + es;
    if (e < 10)
        es = "0" + es;
    String ns = "" + n;
    if (n < 100)
        ns = "0" + ns;
    if (n < 10)
        ns = "0" + ns;

    return firstLetter + secondLetter + es + ns;
}


/**
 * Convert this OSGB grid reference to a latitude/longitude pair using the
 * OSGB36 datum. Note that, the LatLng object may need to be converted to the
 * WGS84 datum depending on the application.
 *
 * @return a LatLng object representing this OSGB grid reference using the
 * OSGB36 datum
 * @since 1.0
 */
public LatLng toLatLng() {
    double OSGB_F0 = 0.9996012717;
    double N0 = -100000.0;
    double E0 = 400000.0;
    double phi0 = Math.toRadians(49.0);
    double lambda0 = Math.toRadians(-2.0);
    double a = RefEll.AIRY_1830.getMaj();
    double b = RefEll.AIRY_1830.getMin();
    double eSquared = RefEll.AIRY_1830.getEcc();
    double phi = 0.0;
    double lambda = 0.0;
    double E = this.easting;
    double N = this.northing;
    double n = (a - b) / (a + b);
    double M = 0.0;
    double phiPrime = ((N - N0) / (a * OSGB_F0)) + phi0;
    do {
        M =
                (b * OSGB_F0)
                        * (((1 + n + ((5.0 / 4.0) * n * n) + ((5.0 / 4.0) * n * n * n)) * (phiPrime - phi0))
                        - (((3 * n) + (3 * n * n) + ((21.0 / 8.0) * n * n * n))
                        * Math.sin(phiPrime - phi0) * Math.cos(phiPrime + phi0))
                        + ((((15.0 / 8.0) * n * n) + ((15.0 / 8.0) * n * n * n))
                        * Math.sin(2.0 * (phiPrime - phi0)) * Math
                        .cos(2.0 * (phiPrime + phi0))) - (((35.0 / 24.0) * n * n * n)
                        * Math.sin(3.0 * (phiPrime - phi0)) * Math
                        .cos(3.0 * (phiPrime + phi0))));
        phiPrime += (N - N0 - M) / (a * OSGB_F0);
    } while ((N - N0 - M) >= 0.001);
    double v =
            a * OSGB_F0
                    * Math.pow(1.0 - eSquared * Util.sinSquared(phiPrime), -0.5);
    double rho =
            a * OSGB_F0 * (1.0 - eSquared)
                    * Math.pow(1.0 - eSquared * Util.sinSquared(phiPrime), -1.5);
    double etaSquared = (v / rho) - 1.0;
    double VII = Math.tan(phiPrime) / (2 * rho * v);
    double VIII =
            (Math.tan(phiPrime) / (24.0 * rho * Math.pow(v, 3.0)))
                    * (5.0 + (3.0 * Util.tanSquared(phiPrime)) + etaSquared - (9.0 * Util
                    .tanSquared(phiPrime) * etaSquared));
    double IX =
            (Math.tan(phiPrime) / (720.0 * rho * Math.pow(v, 5.0)))
                    * (61.0 + (90.0 * Util.tanSquared(phiPrime)) + (45.0 * Util
                    .tanSquared(phiPrime) * Util.tanSquared(phiPrime)));
    double X = Util.sec(phiPrime) / v;
    double XI =
            (Util.sec(phiPrime) / (6.0 * v * v * v))
                    * ((v / rho) + (2 * Util.tanSquared(phiPrime)));
    double XII =
            (Util.sec(phiPrime) / (120.0 * Math.pow(v, 5.0)))
                    * (5.0 + (28.0 * Util.tanSquared(phiPrime)) + (24.0 * Util
                    .tanSquared(phiPrime) * Util.tanSquared(phiPrime)));
    double XIIA =
            (Util.sec(phiPrime) / (5040.0 * Math.pow(v, 7.0)))
                    * (61.0
                    + (662.0 * Util.tanSquared(phiPrime))
                    + (1320.0 * Util.tanSquared(phiPrime) * Util
                    .tanSquared(phiPrime)) + (720.0 * Util.tanSquared(phiPrime)
                    * Util.tanSquared(phiPrime) * Util.tanSquared(phiPrime)));
    phi =
            phiPrime - (VII * Math.pow(E - E0, 2.0))
                    + (VIII * Math.pow(E - E0, 4.0)) - (IX * Math.pow(E - E0, 6.0));
    lambda =
            lambda0 + (X * (E - E0)) - (XI * Math.pow(E - E0, 3.0))
                    + (XII * Math.pow(E - E0, 5.0)) - (XIIA * Math.pow(E - E0, 7.0));

    return new LatLng(Math.toDegrees(phi), Math.toDegrees(lambda));
}


/**
 * Get the easting.
 *
 * @return the easting in metres
 * @since 1.0
 */
public double getEasting() {
    return easting;
}


/**
 * Get the northing.
 *
 * @return the northing in metres
 * @since 1.0
 */
public double getNorthing() {
    return northing;
}

}

提前致谢

0 个答案:

没有答案