when_exe 0.4.4 → 0.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/when_exe.rb +89 -3
- data/lib/when_exe/basictypes.rb +37 -7
- data/lib/when_exe/calendarnote.rb +18 -13
- data/lib/when_exe/calendartypes.rb +3 -9
- data/lib/when_exe/coordinates.rb +23 -373
- data/lib/when_exe/ephemeris.rb +7 -7
- data/lib/when_exe/ephemeris/notes.rb +0 -14
- data/lib/when_exe/events.rb +1851 -0
- data/lib/when_exe/icalendar.rb +121 -4
- data/lib/when_exe/linkeddata.rb +29 -18
- data/lib/when_exe/locales/akt.rb +63 -0
- data/lib/when_exe/locales/locale.rb +60 -11
- data/lib/when_exe/mini_application.rb +14 -8
- data/lib/when_exe/namespace.rb +42 -0
- data/lib/when_exe/parts/enumerator.rb +13 -2
- data/lib/when_exe/parts/geometric_complex.rb +51 -1
- data/lib/when_exe/parts/method_cash.rb +15 -10
- data/lib/when_exe/parts/resource.rb +47 -29
- data/lib/when_exe/region/chinese.rb +4 -3
- data/lib/when_exe/region/chinese/calendars.rb +4 -4
- data/lib/when_exe/region/chinese/epochs.rb +6 -6
- data/lib/when_exe/region/chinese/notes.rb +3 -3
- data/lib/when_exe/region/chinese/twins.rb +6 -6
- data/lib/when_exe/region/islamic.rb +1 -1
- data/lib/when_exe/region/japanese.rb +4 -4
- data/lib/when_exe/region/japanese/eclipses.rb +2 -2
- data/lib/when_exe/region/japanese/location.rb +93 -0
- data/lib/when_exe/region/japanese/notes.rb +29 -11
- data/lib/when_exe/region/japanese/residues.rb +1 -1
- data/lib/when_exe/region/japanese/twins.rb +18 -6
- data/lib/when_exe/region/location.rb +40 -0
- data/lib/when_exe/region/martian.rb +1 -1
- data/lib/when_exe/region/ryukyu.rb +1 -1
- data/lib/when_exe/spatial.rb +611 -0
- data/lib/when_exe/timestandard.rb +3 -3
- data/lib/when_exe/tmobjects.rb +32 -0
- data/lib/when_exe/tmposition.rb +211 -1318
- data/lib/when_exe/tmptypes.rb +1265 -0
- data/lib/when_exe/tmreference.rb +35 -0
- data/lib/when_exe/version.rb +3 -3
- data/test/events/example-datasets +7 -0
- data/test/events/history-dataset.csv +22 -0
- data/test/events/japanese-holiday-index.csv +28 -0
- data/test/events/japanese-holiday.csv +77 -0
- data/test/events/japanese-holiday.ttl +778 -0
- data/test/events/make_events_ttl.rb +18 -0
- data/test/events/mori_wikichoshi.csv +14 -0
- data/test/events/ndl_koyomi.csv +220 -0
- data/test/events/ndl_koyomi_index.csv +44 -0
- data/test/events/primeminister-dataset.csv +19 -0
- data/test/events/shogun-dataset.csv +22 -0
- data/test/events/test-history-dataset-edge-sparql.csv +26 -0
- data/test/events/test-history-dataset-edge.csv +27 -0
- data/test/events/test-history-dataset-sparql.csv +22 -0
- data/test/events/test-history-dataset.csv +23 -0
- data/test/events/test-history-events-edge.ttl +89 -0
- data/test/events/test-history-events.csv +6 -0
- data/test/examples/Terms.m17n +1 -1
- data/test/test.rb +6 -0
- data/test/test/coordinates.rb +2 -2
- data/test/test/events.rb +32 -0
- data/test/test/region/japanese.rb +20 -0
- data/test/test/region/m17n.rb +2 -2
- data/test/test/region/mayan.rb +6 -6
- data/test/test/tmposition.rb +63 -1
- metadata +26 -2
@@ -0,0 +1,40 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
=begin
|
3
|
+
Copyright (C) 2015 Takashi SUGA
|
4
|
+
|
5
|
+
You may use and/or modify this file according to the license
|
6
|
+
described in the LICENSE.txt file included in this archive.
|
7
|
+
=end
|
8
|
+
|
9
|
+
module When::Coordinates
|
10
|
+
|
11
|
+
LocationTable = [
|
12
|
+
|
13
|
+
# 0 : Resource Pool
|
14
|
+
{},
|
15
|
+
|
16
|
+
# 1 : Fine Area Coordinates
|
17
|
+
{},
|
18
|
+
|
19
|
+
# 2 : Middle Area Coordinates
|
20
|
+
Hash.new {|h,k|
|
21
|
+
h[k] = {}
|
22
|
+
},
|
23
|
+
|
24
|
+
# 3 : Wide Area Coordinates
|
25
|
+
Hash.new {|h1,k1|
|
26
|
+
h1[k1] = Hash.new {|h2,k2|
|
27
|
+
h2[k2] = {}
|
28
|
+
}
|
29
|
+
},
|
30
|
+
|
31
|
+
# 4 : Alias Pool
|
32
|
+
Hash.new {|h,k|
|
33
|
+
h[k] = []
|
34
|
+
}
|
35
|
+
]
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
require 'when_exe/region/japanese/location'
|
40
|
+
|
@@ -104,7 +104,7 @@ module When
|
|
104
104
|
# オブジェクトの正規化
|
105
105
|
def _normalize(args=[], options={})
|
106
106
|
@location = When.Resource(@location || '_l:long=0&lat=0&datum=Mars')
|
107
|
-
@mtc0 = MTC0 + @location.long / (360.0 *
|
107
|
+
@mtc0 = MTC0 + @location.long / (360.0 * @location.degree)
|
108
108
|
super
|
109
109
|
end
|
110
110
|
end
|
@@ -82,7 +82,7 @@ module When
|
|
82
82
|
'1609-04-05^#{T:Chinese1645}', ""], # 慶長 14(1609) 4 5 尚寧、島津と和議
|
83
83
|
# (デフォルトは中国暦日)
|
84
84
|
["[<尚豊王>]0", "@A", "name=[尚豊王];1620-09-19"], # 元和 7~寛永 17(1640) 5 4 51歳 甲申
|
85
|
-
["[<尚賢王>]0", "@A", "name=[尚賢王];1640-05-{甲申}"], # 寛永 18~正保 4(1647) 9 22 23歳
|
85
|
+
["[<尚賢王>]0", "@A", "name=[尚賢王];1640-05-{1甲申}"], # 寛永 18~正保 4(1647) 9 22 23歳
|
86
86
|
["[<尚質王>]0", "@A", "name=[尚質王];1647-09-22"], # 慶安 元~寛文 8(1668) 11 17 40歳
|
87
87
|
["[<尚貞王>]0", "@A", "name=[尚貞王];1668-11-17"], # 寛文 9~宝永 6(1709) 7 13 65歳
|
88
88
|
["[<尚益王>]0", "@A", "name=[尚益王];1709-07-13"], # 宝永 7~正徳 2(1712) 7 15 35歳
|
@@ -0,0 +1,611 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
=begin
|
3
|
+
Copyright (C) 2011-2016 Takashi SUGA
|
4
|
+
|
5
|
+
You may use and/or modify this file according to the license described in the LICENSE.txt file included in this archive.
|
6
|
+
=end
|
7
|
+
|
8
|
+
#
|
9
|
+
# 座標の記述に用いる諸オブジェクト
|
10
|
+
#
|
11
|
+
module When::Coordinates
|
12
|
+
|
13
|
+
#
|
14
|
+
# 空間位置
|
15
|
+
#
|
16
|
+
class Spatial < When::BasicTypes::Object
|
17
|
+
|
18
|
+
LabelProperty = 'label'
|
19
|
+
|
20
|
+
include When::Ephemeris
|
21
|
+
|
22
|
+
require 'when_exe/ephemeris/eclipse'
|
23
|
+
|
24
|
+
class << self
|
25
|
+
# When::Coordinates::Spatial のグローバルな設定を行う
|
26
|
+
#
|
27
|
+
# @param [When::Coordinates::Spatial, String] location デフォルトの空間位置を使用する場合、指定する
|
28
|
+
#
|
29
|
+
# @return [void]
|
30
|
+
#
|
31
|
+
# @note
|
32
|
+
# 本メソッドでマルチスレッド対応の管理変数の初期化を行っている。
|
33
|
+
# このため、本メソッド自体はスレッドセーフでない。
|
34
|
+
#
|
35
|
+
def _setup_(location=nil)
|
36
|
+
@_lock_ = Mutex.new if When.multi_thread
|
37
|
+
@_pool = {}
|
38
|
+
@default_location = location
|
39
|
+
end
|
40
|
+
|
41
|
+
# デフォルトの空間位置
|
42
|
+
#
|
43
|
+
# @param [When::Coordinates::Spatial, String] local デフォルトの空間位置
|
44
|
+
#
|
45
|
+
# @return [When::Coordinates::Spatial, String]
|
46
|
+
#
|
47
|
+
# @note
|
48
|
+
# @default_locationは、原則、ライブラリ立ち上げ時に _setup_ で初期化する。
|
49
|
+
# 以降、@default_locationに代入を行っても、すでに生成した When::TM::TemporalPosition 等には反映されない。
|
50
|
+
#
|
51
|
+
def default_location=(local)
|
52
|
+
if @_pool
|
53
|
+
@default_location = local
|
54
|
+
else
|
55
|
+
_setup_(local)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# 設定情報を取得する
|
60
|
+
#
|
61
|
+
# @return [Hash] 設定情報
|
62
|
+
#
|
63
|
+
def _setup_info
|
64
|
+
{:location => @default_location}
|
65
|
+
end
|
66
|
+
|
67
|
+
# デフォルトの空間位置を読みだす
|
68
|
+
#
|
69
|
+
# @return [When::Coordinates::Spatial]
|
70
|
+
#
|
71
|
+
def default_location
|
72
|
+
_default_location[1]
|
73
|
+
end
|
74
|
+
|
75
|
+
# デフォルトの空間位置が When::TM::Clock のローカルタイムから生成されたか?
|
76
|
+
#
|
77
|
+
# @return [true, false]
|
78
|
+
#
|
79
|
+
def is_default_location_derived?
|
80
|
+
location = _default_location
|
81
|
+
location[0] && location[1]
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
# 共通処理
|
87
|
+
def _default_location
|
88
|
+
case @default_location
|
89
|
+
when nil ;
|
90
|
+
when Array ; return @default_location unless @default_location[0]
|
91
|
+
when String ; return (@default_location = [false, When.Resource(@default_location)])
|
92
|
+
else ; return (@default_location = [false, @default_location])
|
93
|
+
end
|
94
|
+
timezone = When::TM::Clock.local_time
|
95
|
+
location = timezone.location if timezone.kind_of?(When::Parts::Timezone)
|
96
|
+
return [true, location]
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# @private
|
101
|
+
HashProperty = [:label, :longitude, :latitude, [:altitude, 0.0], [:datum, When::Ephemeris::Earth], :ref]
|
102
|
+
|
103
|
+
# Degree / Internal Location Unit(16")
|
104
|
+
#
|
105
|
+
# (3600 を 2 の因数で割りつくした値を単位とする)
|
106
|
+
DEGREE = 225
|
107
|
+
|
108
|
+
# 黄道座標 (ecliptic coordinate system)
|
109
|
+
ECLIPTIC = 0
|
110
|
+
|
111
|
+
# 赤道座標 (equatorial coordinate system)
|
112
|
+
EQUATORIAL = 1
|
113
|
+
|
114
|
+
# 赤道座標[時角] (equatorial coordinate system with hour angle)
|
115
|
+
EQUATORIAL_HA = 2
|
116
|
+
|
117
|
+
# 地平座標 (horizontal coordinate system)
|
118
|
+
HORIZONTAL = 3
|
119
|
+
|
120
|
+
# 惑星中心の高度
|
121
|
+
CENTER = :center
|
122
|
+
|
123
|
+
# 角度の単位 (1 => 1度, 225=> 1/225 度)
|
124
|
+
#
|
125
|
+
# @return [Numeric]
|
126
|
+
#
|
127
|
+
attr_reader :degree
|
128
|
+
|
129
|
+
# 北緯を正とする緯度 / 16秒
|
130
|
+
#
|
131
|
+
# @return [Numeric]
|
132
|
+
#
|
133
|
+
attr_reader :lat
|
134
|
+
|
135
|
+
# 東経を正とする経度 / 16秒
|
136
|
+
#
|
137
|
+
# @return [Numeric]
|
138
|
+
#
|
139
|
+
attr_reader :long
|
140
|
+
|
141
|
+
# 高度 / m
|
142
|
+
#
|
143
|
+
# @return [Numeric]
|
144
|
+
# @return [:Center] 天体の中心の場合
|
145
|
+
#
|
146
|
+
attr_reader :alt
|
147
|
+
alias :altitude :alt
|
148
|
+
|
149
|
+
# 座標系
|
150
|
+
#
|
151
|
+
# @return [When::Ephemeris::Datum]
|
152
|
+
#
|
153
|
+
attr_reader :datum
|
154
|
+
|
155
|
+
# 参照
|
156
|
+
#
|
157
|
+
# @return [String] URI
|
158
|
+
#
|
159
|
+
attr_reader :ref
|
160
|
+
|
161
|
+
# 時間帯(オプショナル)
|
162
|
+
#
|
163
|
+
# @return [TZInfo::CountryTimezone]
|
164
|
+
#
|
165
|
+
# TZInfoライブラリから経緯度を取得して使用する
|
166
|
+
#
|
167
|
+
attr_reader :tz
|
168
|
+
|
169
|
+
# 緯度文字列
|
170
|
+
#
|
171
|
+
# @param [Integer] round 秒の小数点以下最大桁数
|
172
|
+
#
|
173
|
+
# @return [String] 緯度文字列(DD.MMSSsss[NS])
|
174
|
+
#
|
175
|
+
def lat_s(round=6)
|
176
|
+
When::Coordinates.to_dms(lat / @degree, 'NS', round)
|
177
|
+
end
|
178
|
+
alias :latitude :lat_s
|
179
|
+
|
180
|
+
# 経度文字列
|
181
|
+
#
|
182
|
+
# @param [Integer] round 秒の小数点以下最大桁数
|
183
|
+
#
|
184
|
+
# @return [String] 経度文字列(DDD.MMSSsss[EW])
|
185
|
+
#
|
186
|
+
def long_s(round=6)
|
187
|
+
When::Coordinates.to_dms(long / @degree, 'EW', round)
|
188
|
+
end
|
189
|
+
alias :longitude :long_s
|
190
|
+
|
191
|
+
# 高度 / m
|
192
|
+
#
|
193
|
+
# @return [Numeric]
|
194
|
+
# @return [:Center] 天体の中心の場合
|
195
|
+
#
|
196
|
+
attr_reader :alt
|
197
|
+
|
198
|
+
# 観測地の地心距離 / kmを返します。
|
199
|
+
#
|
200
|
+
# @return [Numeric]
|
201
|
+
#
|
202
|
+
def obserber_distance
|
203
|
+
l = PI / (90 * @degree) * @lat
|
204
|
+
@datum.surface_radius * (@datum.shape[0]+@datum.shape[1]*cos(l)+@datum.shape[2]*cos(2*l))
|
205
|
+
end
|
206
|
+
|
207
|
+
# 観測地での‘大地’の視半径
|
208
|
+
#
|
209
|
+
# @return [Numeric]
|
210
|
+
#
|
211
|
+
def horizon
|
212
|
+
# 地面以下なら 90度とみなす
|
213
|
+
return 0.25 if @alt == :Center || @alt <= 0
|
214
|
+
|
215
|
+
# 観測地の地心距離 / m
|
216
|
+
r = obserber_distance * 1000.0
|
217
|
+
|
218
|
+
# 大気効果
|
219
|
+
air_effect = @datum.air[1] * @alt / (@datum.air[2] * @alt + r)
|
220
|
+
|
221
|
+
# ‘大地’の視半径
|
222
|
+
asin((1.0+air_effect) * r / (r+@alt)) / CIRCLE
|
223
|
+
end
|
224
|
+
|
225
|
+
# 観測地の地方恒星時 / 時を返します。
|
226
|
+
#
|
227
|
+
# @param [Numeric] t ユリウス日(Terrestrial Time)
|
228
|
+
# @param [When::TM::TemporalPosition] t
|
229
|
+
#
|
230
|
+
# @return [Numeric]
|
231
|
+
#
|
232
|
+
def local_sidereal_time(t)
|
233
|
+
t = +t
|
234
|
+
c = julian_century_from_2000(t)
|
235
|
+
result = @datum.sid[0] + c * (@datum.sid[1] + c * @datum.sid[2]) + @long / (15.0 * @degree)
|
236
|
+
result += (cosc(obl(c)) * delta_p(c) +
|
237
|
+
(t-When::TimeStandard.delta_t_observed(t)/86400+0.5) % 1) * 24 if @datum.kind_of?(Earth)
|
238
|
+
result
|
239
|
+
end
|
240
|
+
|
241
|
+
# 観測地の日心三次元座標(黄道座標)
|
242
|
+
#
|
243
|
+
# @param [Numeric] t ユリウス日(Terrestrial Time)
|
244
|
+
# @param [When::TM::TemporalPosition] t
|
245
|
+
#
|
246
|
+
# @return [Numeric]
|
247
|
+
#
|
248
|
+
def _coords(t)
|
249
|
+
t = +t
|
250
|
+
@datum._coords(t) + _coords_diff(t)
|
251
|
+
end
|
252
|
+
|
253
|
+
private
|
254
|
+
|
255
|
+
# 要素の正規化
|
256
|
+
def _normalize(args=[], options={})
|
257
|
+
|
258
|
+
# 角度の単位は 1/225 度
|
259
|
+
@degree ||= DEGREE
|
260
|
+
|
261
|
+
# 同一視
|
262
|
+
@long ||= @longitude
|
263
|
+
@lat ||= @latitude
|
264
|
+
@alt ||= @altitude
|
265
|
+
|
266
|
+
# 時間帯による指定
|
267
|
+
@tz = When::Parts::Timezone.tz_info[@tz] if @tz.kind_of?(String)
|
268
|
+
if @tz
|
269
|
+
@label ||= When.m17n(@tz.identifier)
|
270
|
+
@long ||= @tz.longitude
|
271
|
+
@lat ||= @tz.latitude
|
272
|
+
end
|
273
|
+
|
274
|
+
# データの整形
|
275
|
+
@label = When::BasicTypes::M17n.new(@label) if @label.kind_of?(Hash)
|
276
|
+
@long = When::Coordinates.to_deg_225(@long, 'EW', @degree) if @long
|
277
|
+
@lat = When::Coordinates.to_deg_225(@lat, 'NS', @degree) if @lat
|
278
|
+
@datum = When.Resource(@datum || 'Earth', '_ep:')
|
279
|
+
@long ||= 0.0
|
280
|
+
@lat ||= 0.0
|
281
|
+
@alt =
|
282
|
+
case @alt
|
283
|
+
when String ; @alt.gsub(/@/, '.').to_f
|
284
|
+
when Numeric ; @alt.to_f
|
285
|
+
when Symbol ; @alt
|
286
|
+
else ; 0.0
|
287
|
+
end
|
288
|
+
|
289
|
+
# 日月食用作業変数
|
290
|
+
@mean = When.Resource(@mean || '_ep:Formula?formula=1L')
|
291
|
+
@ecls = {}
|
292
|
+
|
293
|
+
end
|
294
|
+
|
295
|
+
# 観測地の惑星中心を原点とする三次元座標
|
296
|
+
#
|
297
|
+
# @param [Numeric] t ユリウス日(Terrestrial Time)
|
298
|
+
# @param [When::TM::TemporalPosition] t
|
299
|
+
# @param [Integer] system : 座標系
|
300
|
+
# [ ECLIPTIC = 黄道座標 ]
|
301
|
+
# [ EQUATORIAL = 赤道座標 ]
|
302
|
+
# [ EQUATORIAL_HA = 赤道座標[時角] ]
|
303
|
+
# [ HORIZONTAL = 地平座標 ]
|
304
|
+
#
|
305
|
+
# @return [When::Coordinates::Spatial]
|
306
|
+
#
|
307
|
+
def _coords_diff(t, system=ECLIPTIC)
|
308
|
+
return Coords.polar(0,0,0) if alt == :Center
|
309
|
+
t = +t
|
310
|
+
lat = @lat.to_f / @degree
|
311
|
+
coords = Coords.polar(
|
312
|
+
local_sidereal_time(t) / 24.0,
|
313
|
+
(lat + @datum.shape[3] * sind(2*lat)) / 360.0,
|
314
|
+
(obserber_distance + @alt/1000.0) / AU)
|
315
|
+
case system
|
316
|
+
when ECLIPTIC ; coords.r_to_y(t, @datum)
|
317
|
+
when EQUATORIAL ; coords
|
318
|
+
when EQUATORIAL_HA ; coords.r_to_rh(t, self)
|
319
|
+
when HORIZONTAL ; coords.r_to_h(t, self)
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
# その他のメソッド
|
324
|
+
# When::Coordinates::Spatial で定義されていないメソッドは
|
325
|
+
# 処理を @datum (type: When::Ephemeris::Datum) に委譲する
|
326
|
+
#
|
327
|
+
def method_missing(name, *args, &block)
|
328
|
+
self.class.module_eval %Q{
|
329
|
+
def #{name}(*args, &block)
|
330
|
+
@datum.send("#{name}", *args, &block)
|
331
|
+
end
|
332
|
+
} unless When::Parts::MethodCash.escape(name)
|
333
|
+
@datum.send(name, *args, &block)
|
334
|
+
end
|
335
|
+
|
336
|
+
# @private
|
337
|
+
module Normalize
|
338
|
+
|
339
|
+
private
|
340
|
+
|
341
|
+
# 位置情報
|
342
|
+
#
|
343
|
+
# @return [When::Coordinates::Spatial]
|
344
|
+
#
|
345
|
+
#attr_reader :location
|
346
|
+
|
347
|
+
# 日時要素の境界オブジェクト
|
348
|
+
#
|
349
|
+
# @return [When::Coordinates::Border]
|
350
|
+
#
|
351
|
+
#attr_reader :border
|
352
|
+
|
353
|
+
# 境界計算用の計算オブジェクト
|
354
|
+
#
|
355
|
+
# @return [When::Ephemeris::Formula]
|
356
|
+
#
|
357
|
+
#attr_reader :formula
|
358
|
+
|
359
|
+
#
|
360
|
+
# Temporal Module の Spatial Parts の初期化
|
361
|
+
#
|
362
|
+
def _normalize_spatial
|
363
|
+
|
364
|
+
# Location
|
365
|
+
if (@location||@long||@lat||@alt).kind_of?(String)
|
366
|
+
@location ||= "_l:long=#{@long||0}&lat=#{@lat||0}&alt=#{@alt||0}"
|
367
|
+
@location = When.Resource(@location)
|
368
|
+
end
|
369
|
+
@location ||= @tz_prop.location if @tz_prop
|
370
|
+
|
371
|
+
# Border
|
372
|
+
@border = When.Border(@border) if @border.kind_of?(String)
|
373
|
+
|
374
|
+
# Formula
|
375
|
+
instance_eval('class << self; attr_reader :formula; end') if @location && @border
|
376
|
+
if respond_to?(:formula)
|
377
|
+
extend When::Ephemeris::Formula::ForwardedFormula
|
378
|
+
unless @formula
|
379
|
+
options = {:formula => kind_of?(When::CalendarTypes::SolarYearTableBased) ? '1S' : '1L'}
|
380
|
+
options[:location] = @location if @location
|
381
|
+
@formula = When::Ephemeris::Formula.new(options)
|
382
|
+
end
|
383
|
+
@formula = When.Resource(Array(@formula), '_ep:')
|
384
|
+
end
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
#
|
389
|
+
# イベント管理用範囲オブジェクト
|
390
|
+
#
|
391
|
+
class Range
|
392
|
+
|
393
|
+
class << self
|
394
|
+
|
395
|
+
# 地名を空間座標化する
|
396
|
+
#
|
397
|
+
# @param [String] name 地名または座標
|
398
|
+
#
|
399
|
+
# @return [When::Coordinates::Spatial] or [When::Coordinates::Spatial::Range]
|
400
|
+
#
|
401
|
+
def [](name)
|
402
|
+
source = name.strip
|
403
|
+
case source
|
404
|
+
when /\A(.+)\.\.(.+)\z/ ; return self.new(_instance($1), _instance($2))
|
405
|
+
when /\A([\d.]+)([SN])([\d.]+)([WE])([-+\d.]+)?\z/i ; lat, sn, long, we, alt = $~[1..5]
|
406
|
+
when /\A([\d.]+)([WE])([\d.]+)([SN])([-+\d.]+)?\z/i,
|
407
|
+
/\A([-+\d.]+)(_)([-+\d.]+)(_)?([-+\d.]+)?\z/ ; long, we, lat, sn, alt = $~[1..5]
|
408
|
+
end
|
409
|
+
locations =
|
410
|
+
if long
|
411
|
+
[[
|
412
|
+
When::Coordinates.to_deg_225("#{long}#{we}", 'EW', 1),
|
413
|
+
When::Coordinates.to_deg_225("#{lat }#{sn}", 'NS', 1),
|
414
|
+
(alt || 0).to_f
|
415
|
+
]]
|
416
|
+
else
|
417
|
+
t = When::Coordinates::LocationTable
|
418
|
+
keys = [source]
|
419
|
+
keys.concat(name.names.values) if name.kind_of?(When::BasicTypes::M17n)
|
420
|
+
keys_to_location(keys, t)
|
421
|
+
end
|
422
|
+
return locations unless locations.kind_of?(Array)
|
423
|
+
locations = locations.map {|location|
|
424
|
+
When::Coordinates::Spatial.new({'long'=>location[0], 'lat'=>location[1], 'alt'=>location[2], 'degree'=>1})
|
425
|
+
}
|
426
|
+
locations = locations.size > 1 ? self.new(*locations) : locations.first
|
427
|
+
if t
|
428
|
+
keys.each do |key|
|
429
|
+
t[0][key] = locations
|
430
|
+
end
|
431
|
+
end
|
432
|
+
locations
|
433
|
+
end
|
434
|
+
alias :_instance :[]
|
435
|
+
|
436
|
+
# 地名に空間座標を設定する
|
437
|
+
#
|
438
|
+
# @param [String] name 地名または座標
|
439
|
+
# @param [When::Coordinates::Spatial or When::Coordinates::Spatial::Range] locations 空間座標
|
440
|
+
#
|
441
|
+
def []=(name, locations)
|
442
|
+
keys = [source]
|
443
|
+
keys.concat(name.names.values) if name.kind_of?(When::BasicTypes::M17n)
|
444
|
+
keys.each do |key|
|
445
|
+
When::Coordinates::LocationTable[0][key] = locations
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
449
|
+
private
|
450
|
+
|
451
|
+
Index = {nil=>0, 'N'=>0, 'S'=>-1}
|
452
|
+
|
453
|
+
def keys_to_location(keys, t)
|
454
|
+
keys.each do |key|
|
455
|
+
/\A(.+?)([\dNS])?\z/ =~ key
|
456
|
+
key = t[4][$1][Index[$2] || ($2.to_i-1)] if t[4].key?($1)
|
457
|
+
if t[0].key?(key)
|
458
|
+
return t[0][key]
|
459
|
+
elsif t[1].key?(key)
|
460
|
+
return [t[1][key]]
|
461
|
+
elsif t[2].key?(key)
|
462
|
+
return [t[2][key][:SWB], t[2][key][:NET]]
|
463
|
+
elsif t[3].key?(key)
|
464
|
+
return [t[3][key][:SWB], t[3][key][:NET]]
|
465
|
+
end
|
466
|
+
end
|
467
|
+
raise ArgumentError, keys.first + ' not found'
|
468
|
+
end
|
469
|
+
end
|
470
|
+
|
471
|
+
# 西南下の境界
|
472
|
+
#
|
473
|
+
# @return [When::Coordinates::Spatial]
|
474
|
+
#
|
475
|
+
attr_reader :first
|
476
|
+
|
477
|
+
# 西の境界
|
478
|
+
#
|
479
|
+
# @return [Numeric]
|
480
|
+
#
|
481
|
+
attr_reader :west
|
482
|
+
|
483
|
+
# 南の境界
|
484
|
+
#
|
485
|
+
# @return [Numeric]
|
486
|
+
#
|
487
|
+
attr_reader :south
|
488
|
+
|
489
|
+
# 下の境界
|
490
|
+
#
|
491
|
+
# @return [Numeric]
|
492
|
+
#
|
493
|
+
attr_reader :bottom
|
494
|
+
|
495
|
+
# 東北上の境界
|
496
|
+
#
|
497
|
+
# @return [When::Coordinates::Spatial]
|
498
|
+
#
|
499
|
+
attr_reader :last
|
500
|
+
|
501
|
+
# 東の境界
|
502
|
+
#
|
503
|
+
# @return [Numeric]
|
504
|
+
#
|
505
|
+
attr_reader :east
|
506
|
+
|
507
|
+
# 北の境界
|
508
|
+
#
|
509
|
+
# @return [Numeric]
|
510
|
+
#
|
511
|
+
attr_reader :north
|
512
|
+
|
513
|
+
# 上の境界
|
514
|
+
#
|
515
|
+
# @return [Numeric]
|
516
|
+
#
|
517
|
+
attr_reader :top
|
518
|
+
|
519
|
+
# 東西の範囲
|
520
|
+
#
|
521
|
+
# @return [::Range]
|
522
|
+
#
|
523
|
+
attr_reader :long
|
524
|
+
|
525
|
+
# 南北の範囲
|
526
|
+
#
|
527
|
+
# @return [::Range]
|
528
|
+
#
|
529
|
+
attr_reader :lat
|
530
|
+
|
531
|
+
# 上下の範囲
|
532
|
+
#
|
533
|
+
# @return [::Range]
|
534
|
+
#
|
535
|
+
attr_reader :alt
|
536
|
+
|
537
|
+
# 範囲の重なりの判断が複雑になるか?(ダミー)
|
538
|
+
#
|
539
|
+
# @return [Boolean] false - 単純
|
540
|
+
#
|
541
|
+
def is_complex?
|
542
|
+
false
|
543
|
+
end
|
544
|
+
|
545
|
+
# 終端を除外するか?(ダミー)
|
546
|
+
#
|
547
|
+
# @return [Boolean] false - 除外しない
|
548
|
+
#
|
549
|
+
def exclude_end?
|
550
|
+
false
|
551
|
+
end
|
552
|
+
|
553
|
+
# 指定オブジェクトが範囲内か?
|
554
|
+
#
|
555
|
+
# @param [Object] target 判定するオブジェクト
|
556
|
+
#
|
557
|
+
# @return [Boolean] true - 範囲内のオブジェクトあり, false - 範囲内のオブジェクトなし
|
558
|
+
#
|
559
|
+
def include?(target)
|
560
|
+
case target
|
561
|
+
when When::Coordinates::Spatial
|
562
|
+
@long.include?(target.long) && @lat.include?(target.lat) && @alt.include?(target.alt)
|
563
|
+
when Range
|
564
|
+
@long.include?(target.west) && @lat.include?(target.south) && @alt.include?(target.bottom) &&
|
565
|
+
@long.include?(target.east) && @lat.include?(target.north) && @alt.include?(target.top)
|
566
|
+
else
|
567
|
+
false
|
568
|
+
end
|
569
|
+
end
|
570
|
+
|
571
|
+
#
|
572
|
+
# 範囲の重なりの判断
|
573
|
+
#
|
574
|
+
# @param [Range] range 確認対象の単純範囲オブジェクト
|
575
|
+
#
|
576
|
+
# @return [Boolean] true - 重なる, false - 重ならない
|
577
|
+
#
|
578
|
+
def is_overlaped?(range)
|
579
|
+
case target
|
580
|
+
when When::Coordinates::Spatial
|
581
|
+
@long.include?(target.long) && @lat.include?(target.lat) && @alt.include?(target.alt)
|
582
|
+
when Range
|
583
|
+
@west >= target.east && @north >= target.south && @top >= target.bottom &&
|
584
|
+
@east <= target.west && @south <= target.north && @bottom <= target.top
|
585
|
+
else
|
586
|
+
false
|
587
|
+
end
|
588
|
+
end
|
589
|
+
|
590
|
+
#
|
591
|
+
# イベント管理用範囲オブジェクトの生成
|
592
|
+
#
|
593
|
+
# @param [When::Coordinates::Spatial] first 南西下の境界
|
594
|
+
# @param [When::Coordinates::Spatial] last 東北上の境界
|
595
|
+
#
|
596
|
+
def initialize(first, last)
|
597
|
+
@first = first.kind_of?(Range) ? first.first : first
|
598
|
+
@last = last.kind_of?(Range) ? last.last : last
|
599
|
+
@west = @first.long
|
600
|
+
@south = @first.lat
|
601
|
+
@bottom = @first.alt
|
602
|
+
@east = @last.long
|
603
|
+
@north = @last.lat
|
604
|
+
@top = @last.alt
|
605
|
+
@long = ::Range.new(@west, @east, false)
|
606
|
+
@lat = ::Range.new(@south, @north, false)
|
607
|
+
@alt = ::Range.new(@bottom, @top, false)
|
608
|
+
end
|
609
|
+
end
|
610
|
+
end
|
611
|
+
end
|