| | |
| | | * 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 |
| | | */ |
| | |
| | | /* |
| | | * 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; |
| | |
| | | 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); |
| | | } |
| | | |
| | |
| | | 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; |
| | |
| | | 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); |
| | | } |
| | | |
| | |
| | | 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; |
| | |
| | | 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); |
| | | } |
| | | |
| | |
| | | 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; |
| | |
| | | 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); |
| | | } |
| | | |
| | |
| | | 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; |
| | |
| | | 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; |
| | |
| | | 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)); |
| | | } |
| | | } |
| | | |
| | |
| | | * } |
| | | */ |
| | | |
| | | /** |
| | | * ¥Ñ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); |
| | |
| | | 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; |
| | | } |
| | | } |