9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
# File 'lib/geo_swap.rb', line 9
def lat_long_to_utm(lat, long)
validate_range(lat, long)
lat_radians = degrees_to_radians(lat)
long_radians = degrees_to_radians(long)
zone = Zone.new(lat, long)
origin_radians = degrees_to_radians(zone.origin)
equator_factor = (EQUATORIAL_RADIUS / Math.sqrt(1 - (ECC_SQUARED * (Math.sin(lat_radians) ** 2))))
squared_lat_tangent = Math.tan(lat_radians) ** 2
ecc_prime_factor = ECC_PRIME_SQUARED * (Math.cos(lat_radians) ** 2)
origin_factor = Math.cos(lat_radians) * (long_radians - origin_radians)
ecc_1 = (1 - ecc(1, 1, 4) - ecc(2, 3, 64) - ecc(3, 5, 256))
ecc_2 = ecc(1, 3, 8) + ecc(2, 3, 32) + ecc(3, 45, 1024)
ecc_3 = ecc(2, 15, 256) + ecc(3, 45, 1024)
ecc_4 = ecc(3, 35, 3072)
latRad_1 = lat_radians
latRad_2 = Math.sin(2 * lat_radians)
latRad_3 = Math.sin(4 * lat_radians)
latRad_4 = Math.sin(6 * lat_radians)
northing_factor = EQUATORIAL_RADIUS * (
ecc_1 * latRad_1 -
ecc_2 * latRad_2 +
ecc_3 * latRad_3 -
ecc_4 * latRad_4
)
utm_easting = (MERIDIAN_SCALE * equator_factor *
(origin_factor + (1 - squared_lat_tangent + ecc_prime_factor) *
(origin_factor ** 3) / 6 +
(5 - 18 * squared_lat_tangent + (squared_lat_tangent ** 2) + 72 * ecc_prime_factor - 58 * ECC_PRIME_SQUARED) *
(origin_factor ** 5) / 120) + EASTING_OFFSET)
utm_northing = (
MERIDIAN_SCALE * ( northing_factor + equator_factor * Math.tan(lat_radians) * (origin_factor ** 2) / 2 + (5 - squared_lat_tangent + 9 * ecc_prime_factor + 4 * (ecc_prime_factor ** 2)) * (origin_factor ** 4) / 2 +
(61 - 58 * squared_lat_tangent + (squared_lat_tangent ** 2) + 600 * ecc_prime_factor - 330 * ECC_PRIME_SQUARED) *
(origin_factor ** 6) / 720))
utm_northing += 10000000 if utm_northing < 0
UtmPoint.new(
easting: utm_easting.round,
northing: utm_northing.round,
zone: zone,
hemisphere: (lat < 0 ? 'S' : 'N')
)
end
|