class AIPP::LF::ENR51

D/P/R Zones

Constants

POINT_RADIUS

Radius to use for zones consisting of one point only

SECTIONS

Map sections to whether to parse them

SOURCE_TYPES

Map source types to type and optional local type

Public Instance Methods

parse() click to toggle source
   # File lib/aipp/regions/LF/ENR-5.1.rb
30 def parse
31   skip = false
32   prepare(html: read).css('h4, thead ~ tbody').each do |tag|
33     case tag.name
34     when 'h4'
35       section = tag.text.match(/^ENR ([\d.-]+)/).captures.first
36       skip = !SECTIONS.fetch(section.to_sym)
37       verbose_info "#{skip ? :Skipping : :Parsing} section #{section}"
38     when 'tbody'
39       next if skip
40       airspace = nil
41       tag.css('tr').to_enum.with_index(1).each do |tr, index|
42         tds = tr.css('td')
43         case
44         when tr.attr(:id).match?(/TXT_NAME/)   # airspace
45           airspace = airspace_from tr
46         when tds.count == 1   # big comment on separate row
47           airspace.layers.first.remarks.
48             concat("\n", tds.text.cleanup).
49             remove!(/\((\d)\)\s*\(\1\)\W*/)
50         else   # layer
51           begin
52             tds = tr.css('td')
53             airspace.geometry = geometry_from tds[0].text
54             if airspace.geometry.point?   # convert point to circle
55               airspace.geometry = AIXM.geometry(
56                 AIXM.circle(
57                   center_xy: airspace.geometry.segments.first.xy,
58                   radius: POINT_RADIUS
59                 )
60               )
61             end
62             fail("geometry is not closed") unless airspace.geometry.closed?
63             airspace.add_layer layer_from(tds[1].text)
64             airspace.layers.first.timetable = timetable_from! tds[2].text
65             airspace.layers.first.remarks = remarks_from(tds[2], tds[3], tds[4])
66             if aixm.features.find_by(:airspace, type: airspace.type, id: airspace.id).none?
67               add airspace
68             end
69           rescue => error
70             warn("error parsing airspace `#{airspace.name}' at ##{index}: #{error.message}", pry: error)
71           end
72         end
73       end
74     end
75   end
76 end

Private Instance Methods

airspace_from(tr) click to toggle source
   # File lib/aipp/regions/LF/ENR-5.1.rb
80 def airspace_from(tr)
81   region, source_type, name = tr.text.cleanup.gsub(/\s/, ' ').split(nil, 3)
82   fail "unknown type `#{source_type}'" unless SOURCE_TYPES.has_key? source_type
83   AIXM.airspace(
84     name: [region, source_type, name].join(' '),
85     type: SOURCE_TYPES.dig(source_type, :type),
86     local_type: SOURCE_TYPES.dig(source_type, :local_type)
87   ).tap do |airspace|
88     airspace.source = source(position: tr.line)
89   end
90 end
remarks_from(*parts) click to toggle source
    # File lib/aipp/regions/LF/ENR-5.1.rb
 92 def remarks_from(*parts)
 93   part_titles = ['TIMETABLE', 'RESTRICTION', 'AUTHORITY/CONDITIONS']
 94   [].tap do |remarks|
 95     parts.each.with_index do |part, index|
 96       if part = part.text.gsub(/ +/, ' ').gsub(/(\n ?)+/, "\n").strip.blank_to_nil
 97         unless index.zero? && part == 'H24'
 98           remarks << "**#{part_titles[index]}**\n#{part}"
 99         end
100       end
101     end
102   end.join("\n\n").blank_to_nil
103 end