Module: JapanPlaneRectangular::Functions

Includes:
Constants
Included in:
JapanPlaneRectangular
Defined in:
lib/japan_plane_rectangular/functions.rb

Constant Summary

Constants included from Constants

Constants::ECCENTRICITY, Constants::GRS80_ER, Constants::GRS80_IF, Constants::M0, Constants::ORIGINS

Instance Method Summary collapse

Instance Method Details

#nearest_zone(latlon) ⇒ Object

Find nearest zone number by [Latitude, Longitude]

Parameters:

  • latlon (Array<Float>)
    Latitude, Longitude

Returns:

  • Integer zone number (1~19)



12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/japan_plane_rectangular/functions.rb', line 12

def nearest_zone(latlon)
  min_index = 0
  min_val = Float::MAX
  ORIGINS.each_with_index do |origin, i|
    xy1 = to_xy(latlon, 7)
    xy2 = to_xy(origin, 7)
    d = distance(xy1, xy2)
    if d < min_val
      min_index = i
      min_val = d
    end
  end
  min_index + 1 # zone number
end

#to_latlon(xy, zone) ⇒ Array<Float>

Convert to latlon from XY in zone

Parameters:

  • xy (Array<Float>)
    x, y
  • zone (Integer)

    zone number (1~19)

Returns:

  • (Array<Float>)
    latitude, longitude

Raises:

  • (ArgumentError)


75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/japan_plane_rectangular/functions.rb', line 75

def to_latlon(xy, zone)
  raise ArgumentError, 'Invalid zone number' unless 1 <= zone && zone <= 19
  origin_point = ORIGINS[zone - 1]
  (x, y) = xy

  phi0 = to_radian(origin_point[0])
  lamda0 = to_radian(origin_point[1])

  phi1 = perpendicular(x, phi0)

  ut = GRS80_ER / Math.sqrt(1.0 - ECCENTRICITY**2.0 * Math.sin(phi1)**2.0)
  conp = Math.cos(phi1)
  t1 = Math.tan(phi1)
  eta2 = (ECCENTRICITY**2.0 / (1.0 - ECCENTRICITY**2.0)) * conp**2.0

  yy = y / M0
  v1 = 1.0 + eta2
  v2 = 5.0 + 3.0 * t1**2.0 + 6.0 * eta2 - 6.0 * t1**2.0 * eta2 - 3.0 * eta2**2.0 - 9.0 * t1**2.0 * eta2**2.0
  v3 = 61.0 + 90.0 * t1**2.0 + 45.0 * t1**4.0 + 107.0 * eta2 - 162.0 * t1**2.0 * eta2 - 45.0 * t1**4.0 * eta2
  v4 = 1385.0 + 3633.0 * t1**2.0 + 4095.0 * t1**4.0 + 1575.0 * t1**6.0

  phir = -(v1 / (2.0 * ut**2.0)) * yy**2.0
  phir += (v2 / (24.0 * ut**4.0)) * yy**4.0
  phir -= (v3 / (720.0 * ut**6.0)) * yy**6.0
  phir += (v4 / (40320.0 * ut**8.0)) * yy**8.0
  phir *= t1
  phir += phi1
  phir = to_degree(phir)

  v1 = ut * conp
  v2 = 1.0 + 2.0 * t1**2.0 + eta2
  v3 = 5.0 + 28.0 * t1**2.0 + 24.0 * t1**4.0 + 6.0 * eta2 + 8.0 * t1**2.0 * eta2
  v4 = 61.0 + 662.0 * t1**2.0 + 1320.0 * t1**4.0 + 720.0 * t1**6.0

  lamdar = (1.0 / v1) * yy
  lamdar -= (v2 / (6.0 * ut**2.0 * v1)) * yy**3.0
  lamdar += (v3 / (120.0 * ut**4.0 * v1)) * yy**5.0
  lamdar -= (v4 / (5040.0 * ut**6.0 * v1)) * yy**7.0
  lamdar += lamda0

  lamdar = to_degree(lamdar)

  [phir, lamdar]
end

#to_xy(point, zone) ⇒ Array<Float>

Convert to XY from latlon in zone

Parameters:

  • latlon (Array<Float>)
    latitude, longitude
  • zone (Integer)

    zone number (1~19)

Returns:

  • (Array<Float>)
    x, y

Raises:

  • (ArgumentError)


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
60
61
62
63
64
65
66
67
68
69
# File 'lib/japan_plane_rectangular/functions.rb', line 31

def to_xy(point, zone)
  raise ArgumentError, 'Invalid zone number' unless 1 <= zone && zone <= 19
  origin_point = ORIGINS[zone - 1]

  phi0 = to_radian(origin_point[0])
  lamda0 = to_radian(origin_point[1])

  phi1 = to_radian(point[0])
  lamda1 = to_radian(point[1])

  s0 = meridian_arc_length(phi0)
  s1 = meridian_arc_length(phi1)

  ut = GRS80_ER / Math.sqrt(1.0 - ECCENTRICITY**2.0 * Math.sin(phi1)**2.0)
  conp = Math.cos(phi1)
  t1 = Math.tan(phi1)
  dlamda = lamda1 - lamda0
  eta2 = (ECCENTRICITY**2.0 / (1.0 - ECCENTRICITY**2.0)) * conp**2.0

  v1 = 5.0 - t1**2.0 + 9.0 * eta2 + 4.0 * eta2**2.0
  v2 = -61.0 + 58.0 * t1**2.0 - t1**4.0 - 270.0 * eta2 + 330.0 * t1**2.0 * eta2
  v3 = -1385.0 + 3111.0 * t1**2.0 - 543.0 * t1**4.0 + t1**6.0

  x = ((s1 - s0) + ut * conp**2.0 * t1 * dlamda**2.0 / 2.0 +
      ut * conp**4.0 * t1 * v1 * dlamda**4.0 / 24.0 -
      ut * conp**6.0 * t1 * v2 * dlamda**6.0 / 720.0 -
      ut * conp**8.0 * t1 * v3 * dlamda**8.0 / 40320.0) * M0

  v1 = -1.0 + t1**2.0 - eta2
  v2 = -5.0 + 18.0 * t1**2.0 - t1**4.0 - 14.0 * eta2 + 58.0 * t1**2.0 * eta2
  v3 = -61.0 + 479.0 * t1**2.0 - 179.0 * t1**4.0 + t1**6.0

  y = (ut * conp * dlamda -
      ut * conp**3.0 * v1 * dlamda**3.0 / 6.0 -
      ut * conp**5.0 * v2 * dlamda**5.0 / 120.0 -
      ut * conp**7.0 * v3 * dlamda**7.0 / 5040.0) * M0

  [x, y]
end