forked from geodmms/xdgnjobs

Dennis Kao
2014-01-15 94ae08701bbd7585a0b7e5a92d1975965a503c03
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/TWDDatumConverter.java
@@ -6,11 +6,9 @@
 * TWDDatumConverter
 * User: Ulysses
 * Date: 2007/10/8
 * Time: ¤U¤È 01:35:03
 * To change this template use File | Settings | File Templates.
 */
public abstract class TWDDatumConverter
{
public abstract class TWDDatumConverter {
    /*
     *   Definition of math related value
     */
@@ -51,8 +49,7 @@
    /*
     * datum convert function
     */
    public static Coordinate toTWD97(Coordinate pt)
    {
    public static Coordinate toTWD97(Coordinate pt) {
        double newX, newY, newZ;
        double r, pole, sin_lat, cos_lat;
        double lat, lon, height;
@@ -63,19 +60,15 @@
        lat = pt.y * DEG_RAD;
        height = pt.z * DEG_RAD;
        if ((lat < -HALF_PI) && (lat > -1.001 * HALF_PI))
        {
        if ((lat < -HALF_PI) && (lat > -1.001 * HALF_PI)) {
            lat = -HALF_PI;
        } else if ((lat > HALF_PI) && (lat < 1.001 * HALF_PI))
        {
        } else if ((lat > HALF_PI) && (lat < 1.001 * HALF_PI)) {
            lat = HALF_PI;
        } else if ((lat < -HALF_PI) || (lat > HALF_PI))
        {
        } else if ((lat < -HALF_PI) || (lat > HALF_PI)) {
            return null;
        }
        if (lon > PI)
        {
        if (lon > PI) {
            lon -= (2 * PI);
        }
@@ -90,30 +83,22 @@
        z2 = z1 + TWD67_DZ + TWD67_S * (TWD67_RY * lon - TWD67_RX * lat + height);
        pole = 0.0;
        if (x2 != 0.0)
        {
        if (x2 != 0.0) {
            lon = Math.atan2(y2, x2);
        } else
        {
            if (y2 > 0)
            {
        } else {
            if (y2 > 0) {
                lon = HALF_PI;
            } else if (y2 < 0)
            {
            } else if (y2 < 0) {
                lon = -HALF_PI;
            } else
            {
            } else {
                pole = 1;
                lon = 0;
                if (z2 > 0)
                {
                if (z2 > 0) {
                    lat = HALF_PI;
                } else if (z2 < 0)
                {
                } else if (z2 < 0) {
                    lat = -HALF_PI;
                } else
                {
                } else {
                    lat = HALF_PI;
                    newX = lon * RAD_DEG;
                    newY = lat * RAD_DEG;
@@ -137,19 +122,15 @@
        cos_p = sum / s1;
        r = TWD97_A / Math.sqrt(1.0 - TWD97_ECC * sin_p * sin_p);
        if (cos_p >= COS67_5)
        {
        if (cos_p >= COS67_5) {
            height = q / cos_p - r;
        } else if (cos_p <= -COS67_5)
        {
        } else if (cos_p <= -COS67_5) {
            height = q / -cos_p - r;
        } else
        {
        } else {
            height = z2 / sin_p + r * (TWD97_ECC - 1.0);
        }
        if (pole != 0.0)
        {
        if (pole != 0.0) {
            lat = Math.atan(sin_p / cos_p);
        }
@@ -159,8 +140,7 @@
        return new Coordinate(newX, newY, newZ);
    }
    public static Coordinate toTWD67(Coordinate pt)
    {
    public static Coordinate toTWD67(Coordinate pt) {
        double newX, newY, newZ;
        double r, pole, sin_lat, cos_lat;
        double lat, lon, height;
@@ -171,19 +151,15 @@
        lat = pt.y * DEG_RAD;
        height = pt.z * DEG_RAD;
        if ((lat < -HALF_PI) && (lat > -1.001 * HALF_PI))
        {
        if ((lat < -HALF_PI) && (lat > -1.001 * HALF_PI)) {
            lat = -HALF_PI;
        } else if ((lat > HALF_PI) && (lat < 1.001 * HALF_PI))
        {
        } else if ((lat > HALF_PI) && (lat < 1.001 * HALF_PI)) {
            lat = HALF_PI;
        } else if ((lat < -HALF_PI) || (lat > HALF_PI))
        {
        } else if ((lat < -HALF_PI) || (lat > HALF_PI)) {
            return null;
        }
        if (lon > PI)
        {
        if (lon > PI) {
            lon -= (2 * PI);
        }
@@ -198,30 +174,22 @@
        z2 = z1 - TWD67_DZ - TWD67_S * (TWD67_RY * lon - TWD67_RX * lat + height);
        pole = 0;
        if (x2 != 0.0)
        {
        if (x2 != 0.0) {
            lon = Math.atan2(y2, x2);
        } else
        {
            if (y2 > 0)
            {
        } else {
            if (y2 > 0) {
                lon = HALF_PI;
            } else if (y2 < 0)
            {
            } else if (y2 < 0) {
                lon = -HALF_PI;
            } else
            {
            } else {
                pole = 1;
                lon = 0;
                if (z2 > 0)
                {
                if (z2 > 0) {
                    lat = HALF_PI;
                } else if (z2 < 0)
                {
                } else if (z2 < 0) {
                    lat = -HALF_PI;
                } else
                {
                } else {
                    lat = HALF_PI;
                    newX = lon * RAD_DEG;
                    newY = lat * RAD_DEG;
@@ -245,19 +213,15 @@
        cos_p = sum / s1;
        r = TWD67_A / Math.sqrt(1.0 - TWD67_ECC * sin_p * sin_p);
        if (cos_p >= COS67_5)
        {
        if (cos_p >= COS67_5) {
            height = q / cos_p - r;
        } else if (cos_p <= -COS67_5)
        {
        } else if (cos_p <= -COS67_5) {
            height = q / -cos_p - r;
        } else
        {
        } else {
            height = z2 / sin_p + r * (TWD67_ECC - 1.0);
        }
        if (pole != 0.0)
        {
        if (pole != 0.0) {
            lat = Math.atan(sin_p / cos_p);
        }
@@ -267,8 +231,7 @@
        return new Coordinate(newX, newY, newZ);
    }
    public static Coordinate toTM2(double a, double ecc, double ecc2, double lat, double lon, double scale, double x, double y)
    {
    public static Coordinate toTM2(double a, double ecc, double ecc2, double lat, double lon, double scale, double x, double y) {
        double x0, y0, x1, y1, m0, m1;
        double n, t, c, A;
        double newX, newY;
@@ -284,18 +247,17 @@
        c = ecc2 * Math.pow(Math.cos(y0), 2.0);
        A = (x0 - x1) * Math.cos(y0);
        newX = scale * n
                * (A + (1.0 - t + c) * A * A * A / 6.0
                + (5.0 - 18.0 * t + t * t + 72.0 * c - 58.0 * ecc2) * Math.pow(A, 5.0) / 120.0);
            * (A + (1.0 - t + c) * A * A * A / 6.0
            + (5.0 - 18.0 * t + t * t + 72.0 * c - 58.0 * ecc2) * Math.pow(A, 5.0) / 120.0);
        newY = scale
                * (m1 - m0
                + n * Math.tan(y0)
                * (A * A / 2.0 + (5.0 - t + 9.0 * c + 4 * c * c) * Math.pow(A, 4.0) / 24.0
                + (61.0 - 58.0 * t + t * t + 600.0 * c - 330.0 * ecc2) * Math.pow(A, 6.0) / 720.0));
            * (m1 - m0
            + n * Math.tan(y0)
            * (A * A / 2.0 + (5.0 - t + 9.0 * c + 4 * c * c) * Math.pow(A, 4.0) / 24.0
            + (61.0 - 58.0 * t + t * t + 600.0 * c - 330.0 * ecc2) * Math.pow(A, 6.0) / 720.0));
        return new Coordinate(newX, newY);
    }
    public static Coordinate fromTM2(double a, double ecc, double ecc2, double lat, double lon, double scale, double x, double y)
    {
    public static Coordinate fromTM2(double a, double ecc, double ecc2, double lat, double lon, double scale, double x, double y) {
        double newX, newY;
        double x0, y0, x1, y1, phi, m, m0, mu, e1;
        double c1, t1, n1, r1, d;
@@ -309,35 +271,32 @@
        e1 = (1.0 - Math.sqrt(1.0 - ecc)) / (1.0 + Math.sqrt(1.0 - ecc));
        mu = m / (a * (1.0 - ecc / 4.0 - 3.0 * ecc * ecc / 64.0 - 5.0 * ecc * ecc * ecc / 256.0));
        phi = mu + (3.0 * e1 / 2.0 - 27.0 * Math.pow(e1, 3.0) / 32.0) * Math.sin(2.0 * mu)
                + (21.0 * e1 * e1 / 16.0 - 55.0 * Math.pow(e1, 4.0) / 32.0) * Math.sin(4.0 * mu)
                + 151.0 * Math.pow(e1, 3.0) / 96.0 * Math.sin(6.0 * mu) + 1097.0 * Math.pow(e1, 4.0) / 512.0 * Math.sin(8.0 * mu);
            + (21.0 * e1 * e1 / 16.0 - 55.0 * Math.pow(e1, 4.0) / 32.0) * Math.sin(4.0 * mu)
            + 151.0 * Math.pow(e1, 3.0) / 96.0 * Math.sin(6.0 * mu) + 1097.0 * Math.pow(e1, 4.0) / 512.0 * Math.sin(8.0 * mu);
        c1 = ecc2 * Math.pow(Math.cos(phi), 2.0);
        t1 = Math.pow(Math.tan(phi), 2.0);
        n1 = a / Math.sqrt(1 - ecc * Math.pow(Math.sin(phi), 2.0));
        r1 = a * (1.0 - ecc) / Math.pow(1.0 - ecc * Math.pow(Math.sin(phi), 2.0), 1.5);
        d = x0 / (n1 * scale);
        newX = (x1 + (d - (1.0 + 2.0 * t1 + c1) * Math.pow(d, 3.0) / 6.0
                + (5.0 - 2.0 * c1 + 28.0 * t1 - 3.0 * c1 * c1 + 8.0 * ecc2 + 24.0 * t1 * t1) * Math.pow(d, 5.0)
                / 120.0) / Math.cos(phi)) * RAD_DEG;
            + (5.0 - 2.0 * c1 + 28.0 * t1 - 3.0 * c1 * c1 + 8.0 * ecc2 + 24.0 * t1 * t1) * Math.pow(d, 5.0)
            / 120.0) / Math.cos(phi)) * RAD_DEG;
        newY = (phi
                - n1 * Math.tan(phi) / r1
                * (d * d / 2.0 - (5.0 + 3.0 * t1 + 10.0 * c1 - 4.0 * c1 * c1 - 9.0 * ecc2) * Math.pow(d, 4.0) / 24.0
                + (61.0 + 90.0 * t1 + 298.0 * c1 + 45.0 * t1 * t1 - 252.0 * ecc2 - 3.0 * c1 * c1) * Math.pow(d, 6.0)
                / 72.0)) * RAD_DEG;
            - n1 * Math.tan(phi) / r1
            * (d * d / 2.0 - (5.0 + 3.0 * t1 + 10.0 * c1 - 4.0 * c1 * c1 - 9.0 * ecc2) * Math.pow(d, 4.0) / 24.0
            + (61.0 + 90.0 * t1 + 298.0 * c1 + 45.0 * t1 * t1 - 252.0 * ecc2 - 3.0 * c1 * c1) * Math.pow(d, 6.0)
            / 72.0)) * RAD_DEG;
        return new Coordinate(newX, newY);
    }
    private static double mercator(double y, double a, double ecc)
    {
        if (y == 0.0)
        {
    private static double mercator(double y, double a, double ecc) {
        if (y == 0.0) {
            return 0.0;
        } else
        {
        } else {
            return a * ((1.0 - ecc / 4.0 - 3.0 * ecc * ecc / 64.0 - 5.0 * ecc * ecc * ecc / 256.0) * y
                    - (3.0 * ecc / 8.0 + 3.0 * ecc * ecc / 32.0 + 45.0 * ecc * ecc * ecc / 1024.0) * Math.sin(2.0 * y)
                    + (15.0 * ecc * ecc / 256.0 + 45.0 * ecc * ecc * ecc / 1024.0) * Math.sin(4.0 * y)
                    - (35.0 * ecc * ecc * ecc / 3072.0) * Math.sin(6.0 * y));
                - (3.0 * ecc / 8.0 + 3.0 * ecc * ecc / 32.0 + 45.0 * ecc * ecc * ecc / 1024.0) * Math.sin(2.0 * y)
                + (15.0 * ecc * ecc / 256.0 + 45.0 * ecc * ecc * ecc / 1024.0) * Math.sin(4.0 * y)
                - (35.0 * ecc * ecc * ecc / 3072.0) * Math.sin(6.0 * y));
        }
    }
@@ -490,14 +449,7 @@
     * }
     */
    /**
     * ¥ÑTM2®y¼ÐÂà´«¦ÜTWD97®y¼Ð
     *
     * @param pt TM2¦ì¸m
     * @return ·sªºTWD97®y¼Ð
     */
    public static Coordinate fromTM2ToTWD97(Coordinate pt)
    {
    public static Coordinate fromTM2ToEPSG3826(Coordinate pt) {
        Coordinate ptTWD67 = fromTM2(TWD67_A, TWD67_ECC, TWD67_ECC2, 0, 121, TWD67_TM2, pt.x - 250000.0, pt.y);
        ptTWD67.z = 0;
        Coordinate ptTWD97 = toTWD97(ptTWD67);
@@ -506,4 +458,14 @@
        pt97TM2.y -= 200.0;
        return pt97TM2;
    }
    public static Coordinate fromTM2ToEPSG3825(Coordinate pt) {
        Coordinate ptTWD67 = fromTM2(TWD67_A, TWD67_ECC, TWD67_ECC2, 0, 191, TWD67_TM2, pt.x - 250000.0, pt.y);
        ptTWD67.z = 0;
        Coordinate ptTWD97 = toTWD97(ptTWD67);
        Coordinate pt97TM2 = toTM2(TWD97_A, TWD97_ECC, TWD97_ECC2, 0, 191, TWD97_TM2, ptTWD97.x, ptTWD97.y);
        pt97TM2.x += 250000.0;
        pt97TM2.y -= 200.0;
        return pt97TM2;
    }
}