aipp 0.1.3 → 0.2.0

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.
@@ -1,32 +0,0 @@
1
- module AIPP
2
- module Parsers
3
- include Helpers::URL
4
- include Helpers::HTML
5
-
6
- def convert!
7
- cleanup!
8
- html.css('tbody').each do |tbody|
9
- tbody.css('tr').to_enum.with_index(1).each do |tr, index|
10
- break if index >= @limit
11
- tds = tr.css('td')
12
- designated_point = AIXM.designated_point(
13
- type: :icao,
14
- id: tds[0].text.strip,
15
- xy: xy_from(tds[1])
16
- )
17
- aixm.features << designated_point
18
- rescue => exception
19
- warn("WARNING: error parsing designated point at ##{index}: #{exception.message}", binding)
20
- end
21
- end
22
- true
23
- end
24
-
25
- private
26
-
27
- def xy_from(td)
28
- parts = td.text.strip.split(/\s+/)
29
- AIXM.xy(lat: parts[0], long: parts[1])
30
- end
31
- end
32
- end
@@ -1,134 +0,0 @@
1
- module AIPP
2
- module Parsers
3
- include Helpers::URL
4
- include Helpers::HTML
5
- using AIPP::Refinements
6
- using AIXM::Refinements
7
-
8
- TYPES = {
9
- 'D' => 'D',
10
- 'P' => 'P',
11
- 'R' => 'R',
12
- 'ZIT' => 'P'
13
- }.freeze
14
-
15
- BORDERS = {
16
- 'franco-allemande' => 'FRANCE_GERMANY',
17
- 'franco-espagnole' => 'FRANCE_SPAIN',
18
- 'franco-italienne' => 'FRANCE_ITALY',
19
- 'franco-suisse' => 'FRANCE_SWITZERLAND',
20
- 'franco-luxembourgeoise' => 'FRANCE_LUXEMBOURG',
21
- 'franco-belge' => 'BELGIUM_FRANCE'
22
- }.freeze
23
-
24
- def convert!
25
- cleanup!
26
- html.css('tbody:has(tr[id^=mid])').each do |tbody|
27
- airspace = nil
28
- tbody.css('tr').to_enum.with_index(1).each do |tr, index|
29
- if tr.attr(:class) =~ /keep-with-next-row/
30
- airspace = airspace_from tr
31
- else
32
- begin
33
- tds = tr.css('td')
34
- airspace.geometry = geometry_from tds[0]
35
- airspace.class_layers << class_layer_from(tds[1])
36
- airspace.schedule = schedule_from tds[2]
37
- airspace.remarks = remarks_from(tds[2], tds[3], tds[4])
38
- fail "airspace `#{airspace.name}' is not complete" unless airspace.complete?
39
- aixm.features << airspace
40
- break if index / 2 >= @limit
41
- rescue => exception
42
- warn("WARNING: error parsing airspace `#{airspace.name}' at ##{index}: #{exception.message}", binding)
43
- end
44
- end
45
- end
46
- end
47
- true
48
- end
49
-
50
- private
51
-
52
- def airspace_from(tr)
53
- spans = tr.css(:span)
54
- AIXM.airspace(
55
- name: [spans[1], spans[2], spans[3], spans[5].text.blank_to_nil].compact.join(' '),
56
- short_name: [spans[1], spans[2], spans[3]].compact.join(' '),
57
- type: TYPES.fetch(spans[2].text)
58
- )
59
- end
60
-
61
- def geometry_from(td)
62
- AIXM.geometry.tap do |geometry|
63
- buffer = {}
64
- td.text.gsub(/\s+/, ' ').strip.split(/ - /).append('end').each do |element|
65
- case element
66
- when /frontière (.+)/i
67
- geometry << AIXM.border(
68
- xy: buffer.delete(:xy),
69
- name: BORDERS.fetch($1)
70
- )
71
- when /arc (anti-)?horaire .+ sur (\S+) , (\S+)/i
72
- geometry << AIXM.arc(
73
- xy: buffer.delete(:xy),
74
- center_xy: AIXM.xy(lat: $2, long: $3),
75
- clockwise: $1.nil?
76
- )
77
- when /cercle de ([\d\.]+) (NM|km|m) .+ sur (\S+) , (\S+)/i
78
- geometry << AIXM.circle(
79
- center_xy: AIXM.xy(lat: $3, long: $4),
80
- radius: $1.to_f.to_km(from: $2).round(3)
81
- )
82
- when /end|(\S+) , (\S+)/
83
- geometry << AIXM.point(xy: buffer[:xy]) if buffer.has_key?(:xy)
84
- buffer[:xy] = AIXM.xy(lat: $1, long: $2) if $1
85
- else
86
- fail "geometry `#{element}' not recognized"
87
- end
88
- end
89
- end
90
- end
91
-
92
- def class_layer_from(td)
93
- above, below = td.text.gsub(/ /, '').split(/\n+/).select(&:blank_to_nil).split(/---+/)
94
- above.reverse!
95
- AIXM.class_layer(
96
- vertical_limits: AIXM.vertical_limits(
97
- max_z: z_from(above[1]),
98
- upper_z: z_from(above[0]),
99
- lower_z: z_from(below[0]),
100
- min_z: z_from(below[1])
101
- )
102
- )
103
- end
104
-
105
- def z_from(limit)
106
- case limit
107
- when nil then nil
108
- when 'SFC' then AIXM::GROUND
109
- when 'UNL' then AIXM::UNLIMITED
110
- when /(\d+)ftASFC/ then AIXM.z($1.to_i, :qfe)
111
- when /(\d+)ftAMSL/ then AIXM.z($1.to_i, :qnh)
112
- when /FL(\d+)/ then AIXM.z($1.to_i, :qne)
113
- else fail "z `#{limit}' not recognized"
114
- end
115
- end
116
-
117
- def schedule_from(td)
118
- AIXM::H24 if td.text.gsub(/\W/, '') == 'H24'
119
- end
120
-
121
- def remarks_from(*parts)
122
- part_titles = ['SCHEDULE', 'RESTRICTION', 'AUTHORITY/CONDITIONS']
123
- [].tap do |remarks|
124
- parts.each.with_index do |part, index|
125
- if part = part.text.gsub(/ +/, ' ').gsub(/(\n ?)+/, "\n").strip.blank_to_nil
126
- unless index.zero? && part == 'H24'
127
- remarks << "#{part_titles[index]}:\n#{part}"
128
- end
129
- end
130
- end
131
- end.join("\n\n").blank_to_nil
132
- end
133
- end
134
- end
@@ -1,11 +0,0 @@
1
- module AIPP
2
- module Helpers
3
- module HTML
4
-
5
- def cleanup!
6
- html.css('del').each { |n| n.remove } # remove deleted entries
7
- end
8
-
9
- end
10
- end
11
- end
@@ -1,15 +0,0 @@
1
- module AIPP
2
- module Helpers
3
- module URL
4
-
5
- def url
6
- "https://www.sia.aviation-civile.gouv.fr/dvd/eAIP_%s/FRANCE/AIRAC-%s/html/eAIP/FR-%s-fr-FR.html" % [
7
- aixm.effective_at.strftime('%d_%^b_%Y'), # 04_JAN_2018
8
- aixm.effective_at.to_date.xmlschema, # 2018-01-04
9
- @aip # ENR-5.1
10
- ]
11
- end
12
-
13
- end
14
- end
15
- end