Class: When::Coordinates::Spatial

Inherits:
BasicTypes::Object show all
Includes:
Ephemeris
Defined in:
lib/when_exe/coordinates.rb,
lib/when_exe/ephemeris/eclipse.rb

Overview

Copyright © 2014-2015 Takashi SUGA

You may use and/or modify this file according to the license described in the LICENSE.txt file included in this archive.

Defined Under Namespace

Modules: Normalize

Constant Summary collapse

LabelProperty =
'label'
HashProperty =
[:label, :longitude, :latitude, [:altitude, 0.0], [:datum, When::Ephemeris::Earth], :ref]
DEGREE =

Degree / Internal Location Unit(16“)

(3600 を 2 の因数で割りつくした値を単位とする)
225
ECLIPTIC =

黄道座標 (ecliptic coordinate system)

0
EQUATORIAL =

赤道座標 (equatorial coordinate system)

1
EQUATORIAL_HA =

赤道座標 (equatorial coordinate system with hour angle)

2
HORIZONTAL =

地平座標 (horizontal coordinate system)

3
CENTER =

惑星中心の高度

:center
EclipseHalfYear =
(346 + (14*3600+52*60+54.965) / 86400) / 2
EclipseRange =
(75.0..120.0)

Constants included from Ephemeris

Ephemeris::AU, Ephemeris::AcS, Ephemeris::BCENT, Ephemeris::C0, Ephemeris::CIRCLE, Ephemeris::COS, Ephemeris::COSL, Ephemeris::COSLT, Ephemeris::COST, Ephemeris::DAY, Ephemeris::DEG, Ephemeris::EPOCH1800, Ephemeris::EPOCH1900, Ephemeris::EPOCH1975, Ephemeris::EPOCH2000, Ephemeris::FARAWAY, Ephemeris::JCENT, Ephemeris::JYEAR, Ephemeris::Jupiter, Ephemeris::LIN, Ephemeris::Mars, Ephemeris::Mercury, Ephemeris::Neptune, Ephemeris::P0B, Ephemeris::P0L, Ephemeris::P0P, Ephemeris::P0dB, Ephemeris::P0dL, Ephemeris::P1B, Ephemeris::P1L, Ephemeris::P1R, Ephemeris::P2B, Ephemeris::P2L, Ephemeris::P2Q, Ephemeris::P2dL, Ephemeris::P3L, Ephemeris::P3Q, Ephemeris::P4B, Ephemeris::P4L, Ephemeris::P4Q, Ephemeris::P4dL, Ephemeris::P5B, Ephemeris::P5L, Ephemeris::P5Q, Ephemeris::P5dL, Ephemeris::P5l, Ephemeris::P5n, Ephemeris::P5r, Ephemeris::P5t, Ephemeris::P6B, Ephemeris::P6L, Ephemeris::P6Q, Ephemeris::P6dL, Ephemeris::P6l, Ephemeris::P6n, Ephemeris::P6r, Ephemeris::P6t, Ephemeris::P7B, Ephemeris::P7L, Ephemeris::P7R, Ephemeris::P8B, Ephemeris::P8L, Ephemeris::P8R, Ephemeris::P9B, Ephemeris::P9L, Ephemeris::P9R, Ephemeris::PSEC, Ephemeris::Pluto, Ephemeris::SIN, Ephemeris::SINL, Ephemeris::SINLT, Ephemeris::SINT, Ephemeris::Saturn, Ephemeris::Uranus, Ephemeris::Venus

Constants included from Parts::Resource

Parts::Resource::ConstList, Parts::Resource::ConstTypes, Parts::Resource::IRIDecode, Parts::Resource::IRIDecodeTable, Parts::Resource::IRIEncode, Parts::Resource::IRIEncodeTable, Parts::Resource::IRIHeader

Instance Attribute Summary collapse

Attributes inherited from BasicTypes::Object

#label

Attributes included from Parts::Resource

#_pool, #child, #keys, #locale, #namespace

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Ephemeris

_adjust, _rot, _to_p2, _to_p3, _to_r3, acos, asin, cosc, cosd, delta_e, delta_p, julian_century_from_2000, julian_year_from_1975, obl, polynomial, root, sinc, sind, tanc, tand, trigonometric

Methods included from Parts::Resource

#[], #^, _abbreviation_to_iri, _decode, _encode, _extract_prefix, _instance, _instantiate, _parse, _path_with_prefix, _replace_tags, _simplify_path, base_uri, #each, #enum_for, #hierarchy, #include?, #included?, #iri, #leaf?, #m17n, #map, #next, #parent, #prev, #registered?, root_dir

Methods included from Parts::Resource::Pool

#[], #[]=, #_pool, #_setup_, #pool_keys

Methods included from Parts::Resource::Synchronize

#synchronize

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object (private)

その他のメソッド

When::Coordinates::Spatial で定義されていないメソッドは
処理を @datum (type: When::Ephemeris::Datum) に委譲する


1548
1549
1550
1551
1552
1553
1554
1555
# File 'lib/when_exe/coordinates.rb', line 1548

def method_missing(name, *args, &block)
  self.class.module_eval %Q{
    def #{name}(*args, &block)
      @datum.send("#{name}", *args, &block)
    end
  } unless When::Parts::MethodCash.escape(name)
  @datum.send(name, *args, &block)
end

Instance Attribute Details

#altNumeric, :Center (readonly) Also known as: altitude

高度 / m

Returns:

  • (Numeric)
  • (:Center)

    天体の中心の場合



1373
1374
1375
# File 'lib/when_exe/coordinates.rb', line 1373

def alt
  @alt
end

#datumWhen::Ephemeris::Datum (readonly)

座標系



1380
1381
1382
# File 'lib/when_exe/coordinates.rb', line 1380

def datum
  @datum
end

#latNumeric (readonly)

北緯を正とする緯度 / 16秒

Returns:



1360
1361
1362
# File 'lib/when_exe/coordinates.rb', line 1360

def lat
  @lat
end

#longNumeric (readonly)

東経を正とする経度 / 16秒

Returns:



1366
1367
1368
# File 'lib/when_exe/coordinates.rb', line 1366

def long
  @long
end

#refString (readonly)

参照

Returns:



1386
1387
1388
# File 'lib/when_exe/coordinates.rb', line 1386

def ref
  @ref
end

#tzTZInfo::CountryTimezone (readonly)

時間帯(オプショナル)

Returns:

  • (TZInfo::CountryTimezone)

    TZInfoライブラリから経緯度を取得して使用する



1394
1395
1396
# File 'lib/when_exe/coordinates.rb', line 1394

def tz
  @tz
end

Class Method Details

._setup_(location = nil) ⇒ void

Note:

本メソッドでマルチスレッド対応の管理変数の初期化を行っている。 このため、本メソッド自体はスレッドセーフでない。

This method returns an undefined value.

When::Coordinates::Spatial のグローバルな設定を行う

Parameters:



1268
1269
1270
1271
1272
# File 'lib/when_exe/coordinates.rb', line 1268

def _setup_(location=nil)
  @_lock_ = Mutex.new if When.multi_thread
  @_pool  = {}
  @default_location = location
end

._setup_infoHash

設定情報を取得する

Returns:

  • (Hash)

    設定情報



1296
1297
1298
# File 'lib/when_exe/coordinates.rb', line 1296

def _setup_info
  {:location => @default_location}
end

.default_locationWhen::Coordinates::Spatial

デフォルトの空間位置を読みだす



1304
1305
1306
# File 'lib/when_exe/coordinates.rb', line 1304

def default_location
  _default_location[1]
end

.default_location=(local) ⇒ When::Coordinates::Spatial, String

Note:

@default_locationは、原則、ライブラリ立ち上げ時に setup で初期化する。 以降、@default_locationに代入を行っても、すでに生成した When::TM::TemporalPosition 等には反映されない。

デフォルトの空間位置

Parameters:

Returns:



1284
1285
1286
1287
1288
1289
1290
# File 'lib/when_exe/coordinates.rb', line 1284

def default_location=(local)
  if @_pool
    @default_location = local
  else
    _setup_(local)
  end
end

.is_default_location_derived?true, false

デフォルトの空間位置が When::TM::Clock のローカルタイムから生成されたか?

Returns:

  • (true, false)


1312
1313
1314
1315
# File 'lib/when_exe/coordinates.rb', line 1312

def is_default_location_derived?
  location = _default_location
  location[0] && location[1]
end

Instance Method Details

#_coords(t) ⇒ Numeric

観測地の日心三次元座標(黄道座標)

Parameters:

Returns:



1475
1476
1477
1478
# File 'lib/when_exe/coordinates.rb', line 1475

def _coords(t)
  t   = +t
  @datum._coords(t) + _coords_diff(t)
end

#eclipse_info(date, location, target, base, l_for_h = [location, base]) ⇒ Array<String, Numeric, Array<Array<Numeric or When::TM::TemporalPosition, String>>>

食の情報

Parameters:

Returns:



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/when_exe/ephemeris/eclipse.rb', line 104

def eclipse_info(date, location, target, base, l_for_h=[location, base])

  tc  = When::Ephemeris.root(+date) {|t|            # 離角最小日時
          base.elongation(t, target, location)**2
        }
  mag = base.phase_of_eclipse(tc, target, location) # 食分
  return nil unless mag >= 0                        # 食なし

  t1, t4 = [-0.1, +0.1].map {|dt|                   # 第1, 第4接触
    When::Ephemeris.root(tc+dt, 0) {|t|
      base.phase_of_eclipse(t, target, location)
    }
  }

  if mag >= 1
    category = 'T'
    t2, t3 = [-0.01, +0.01].map {|dt|               # 第2, 第3接触
      When::Ephemeris.root(tc+dt, 1.0) {|t|
        base.phase_of_eclipse(t, target, location)
      }
    }
  elsif target.phase_of_eclipse(tc, base, location) >= 1
    category = 'A'
    t2, t3 = [-0.01, +0.01].map {|dt|               # 第2, 第3接触
      When::Ephemeris.root(tc+dt, 1.0) {|t|
        target.phase_of_eclipse(t, base, location)
      }
    }
  else
    category = 'P'
  end
  ts = [t1,t2,tc,t3,t4].compact

  form = When::Ephemeris::Formula.new(:location=>l_for_h[0])
  height, azimuth = ts.map {|t|                     # 基準天体の高度・方位角
     coord = form._coords(t, HORIZONTAL, l_for_h[1])
    [coord.theta * 360, ((0.5-coord.phi)-(0.5-coord.phi).floor) * 360]
  }.transpose
  return nil  unless height.max >= 0                # 見えない食
  category += 'B' if height.min <  0                # 地平線下で食が始まる/終わる

  [category, mag, [ts.map {|t| form._to_seed_type(t, date)}, height, azimuth].transpose]

rescue RangeError
  nil
end

#horizonNumeric

観測地での‘大地’の視半径

Returns:



1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
# File 'lib/when_exe/coordinates.rb', line 1438

def horizon
  # 地面以下なら 90度とみなす
  return 0.25 if @alt == :Center || @alt <= 0

  # 観測地の地心距離 / m
  r = obserber_distance * 1000.0

  # 大気効果
  air_effect = @datum.air[1] * @alt / (@datum.air[2] * @alt + r)

  # ‘大地’の視半径
  asin((1.0+air_effect) * r / (r+@alt)) / CIRCLE
end

#lat_sString Also known as: latitude

緯度文字列

Parameters:

  • round (Integer)

    秒の小数点以下最大桁数

Returns:



1402
1403
1404
# File 'lib/when_exe/coordinates.rb', line 1402

def lat_s
  When::Coordinates.to_dms(lat / When::Coordinates::Spatial::DEGREE, 'NS', round=6)
end

#local_sidereal_time(t) ⇒ Numeric

観測地の地方恒星時 / 時を返します。

Parameters:

Returns:



1459
1460
1461
1462
1463
1464
1465
1466
# File 'lib/when_exe/coordinates.rb', line 1459

def local_sidereal_time(t)
  t = +t
  c = julian_century_from_2000(t)
  result  = @datum.sid[0] + c * (@datum.sid[1] + c * @datum.sid[2]) + @long / (15.0 * DEGREE)
  result += (cosc(obl(c)) * delta_p(c) +
             (t-When::TimeStandard.delta_t_observed(t)/86400+0.5) % 1) * 24 if @datum.kind_of?(Earth)
  result
end

#long_sString Also known as: longitude

経度文字列

Parameters:

  • round (Integer)

    秒の小数点以下最大桁数

Returns:



1413
1414
1415
# File 'lib/when_exe/coordinates.rb', line 1413

def long_s
  When::Coordinates.to_dms(long / When::Coordinates::Spatial::DEGREE, 'EW', round=6)
end

#lunar_eclipse(date, margin = When::PT6H, &block) ⇒ Array<String, Numeric, Array<Array<Numeric or When::TM::TemporalPosition, String>>>

月食の情報

Parameters:

Returns:



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/when_exe/ephemeris/eclipse.rb', line 62

def lunar_eclipse(date, margin=When::PT6H, &block)
  if date.kind_of?(Range)
    last  = date.last.to_i
    last -= 1 if date.exclude_end?
    first = date.first.to_i
    date  = date.first
  end
  clock = date.clock && (date.clock.tz_prop || date.clock.label)
  cn    = (@mean.time_to_cn(date)+0.25).floor+0.5
  list  = []
  loop do
    unless @ecls.key?([cn,clock.to_s])
      time = @mean.cn_to_time(cn)
      data = EclipseRange.include?(time % EclipseHalfYear) ?
               eclipse_info(@mean._to_seed_type(time, date), When.Resource('_ep:Earth'), When.Resource('_ep:Moon'),
                 When.Resource('_ep:Shadow'), [self, When.Resource('_ep:Moon')]) : nil
      @ecls[[cn,clock.to_s]] = data ? [(data[2][data[2].size / 2][0]-margin).to_i, data] : nil
    end
    key, info = @ecls[[cn,clock.to_s]]
    return info unless first
    list << (block_given? ? yield(info) : info) if key && first <= key && key <= last
    break if (key || first) >= last
    cn += 1
  end
  return list
end

#obserber_distanceNumeric

観測地の地心距離 / kmを返します。

Returns:



1429
1430
1431
1432
# File 'lib/when_exe/coordinates.rb', line 1429

def obserber_distance
  l = PI / (90 * DEGREE) * @lat
  @datum.surface_radius * (@datum.shape[0]+@datum.shape[1]*cos(l)+@datum.shape[2]*cos(2*l))
end

#solar_eclipse(date, &block) ⇒ Array<String, Numeric, Array<Array<Numeric or When::TM::TemporalPosition, String>>>

日食の情報

Parameters:

Returns:



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
# File 'lib/when_exe/ephemeris/eclipse.rb', line 25

def solar_eclipse(date, &block)
  if date.kind_of?(Range)
    last  = date.last.to_i
    last -= 1 if date.exclude_end?
    first = date.first.to_i
    date  = date.first
  end
  clock = date.clock && (date.clock.tz_prop || date.clock.label)
  cn    = @mean.time_to_cn(date).round
  list  = []
  loop do
    unless @ecls.key?([cn,clock.to_s])
      time = @mean.cn_to_time(cn)
      data = EclipseRange.include?(time % EclipseHalfYear) ?
              eclipse_info(@mean._to_seed_type(time, date), self, When.Resource('_ep:Sun'), When.Resource('_ep:Moon')) : nil
      @ecls[[cn,clock.to_s]] = data ? [data[2][data[2].size / 2][0].to_i, data] : nil
    end
    key, info = @ecls[[cn,clock.to_s]]
    return info unless first
    list << (block_given? ? yield(info) : info) if key && first <= key && key <= last
    break if (key || first) >= last
    cn += 1
  end
  return list
end