class AIPP::Parser
AIP
parser infrastructure
Attributes
aixm[R]
@return [AIXM::Document] target document
borders[R]
@return [Hash] map from border names to border objects
cache[R]
@return [OpenStruct] object cache
config[R]
@return [Hash] configuration read from config.yml
fixtures[R]
@return [Hash] map from AIP
name to fixtures
options[R]
@return [Hash] passed command line arguments
Public Class Methods
new(options:)
click to toggle source
# File lib/aipp/parser.rb 26 def initialize(options:) 27 @options = options 28 @options[:storage] = options[:storage].join(options[:region]) 29 @options[:storage].mkpath 30 @config = {} 31 @aixm = AIXM.document(effective_at: @options[:airac].date) 32 @dependencies = THash.new 33 @fixtures = {} 34 @borders = {} 35 @cache = OpenStruct.new 36 AIXM.send("#{options[:schema]}!") 37 AIXM.config.region = options[:region] 38 end
Public Instance Methods
parse_aip()
click to toggle source
Parse AIP
by invoking the parser classes for the current region.
# File lib/aipp/parser.rb 80 def parse_aip 81 info("AIRAC #{options[:airac].id} effective #{options[:airac].date}", color: :green) 82 AIPP::Downloader.new(storage: options[:storage], source: options[:airac].date.xmlschema) do |downloader| 83 @dependencies.tsort(options[:aip]).each do |aip| 84 info("Parsing #{aip}") 85 ("AIPP::%s::%s" % [options[:region], aip.remove(/\W/).classify]).constantize.new( 86 aip: aip, 87 downloader: downloader, 88 fixture: @fixtures[aip], 89 parser: self 90 ).attach_patches.tap(&:parse).detach_patches 91 end 92 end 93 if options[:grouped_obstacles] 94 info("Grouping obstacles") 95 aixm.group_obstacles! 96 end 97 info("Counting #{aixm.features.count} features") 98 end
read_config()
click to toggle source
Read the configuration from config.yml.
# File lib/aipp/parser.rb 41 def read_config 42 info("Reading config.yml") 43 @config = YAML.load_file(config_file, fallback: {}).transform_keys(&:to_sym) if config_file.exist? 44 @config[:namespace] ||= SecureRandom.uuid 45 @aixm.namespace = @config[:namespace] 46 end
read_region()
click to toggle source
Read the region directory and build the dependency list.
# File lib/aipp/parser.rb 49 def read_region 50 info("Reading region #{options[:region]}") 51 dir = Pathname(__FILE__).dirname.join('regions', options[:region]) 52 fail("unknown region `#{options[:region]}'") unless dir.exist? 53 # Fixtures 54 dir.glob('fixtures/*.yml').each do |file| 55 verbose_info "Reading fixture fixtures/#{file.basename}" 56 fixture = YAML.load_file(file) 57 @fixtures[file.basename('.yml').to_s] = fixture 58 end 59 # Borders 60 dir.glob('borders/*.geojson').each do |file| 61 verbose_info "Reading border borders/#{file.basename}" 62 border = AIPP::Border.new(file) 63 @borders[border.name] = border 64 end 65 # Helpers 66 dir.glob('helpers/*.rb').each do |file| 67 verbose_info "Reading helper helpers/#{file.basename}" 68 require file 69 end 70 # Parsers 71 dir.glob('*.rb').each do |file| 72 verbose_info "Requiring #{file.basename}" 73 require file 74 aip = file.basename('.*').to_s 75 @dependencies[aip] = ("AIPP::%s::%s::DEPENDS" % [options[:region], aip.remove(/\W/).classify]).constantize 76 end 77 end
validate_aixm()
click to toggle source
Validate the AIXM document.
@raise [RuntimeError] if the document is not valid
# File lib/aipp/parser.rb 103 def validate_aixm 104 info("Detecting duplicates") 105 if (duplicates = aixm.features.duplicates).any? 106 message = "duplicates found:\n" + duplicates.map { "#{_1.inspect} from #{_1.source}" }.join("\n") 107 @options[:force] ? warn(message, pry: binding) : fail(message) 108 end 109 info("Validating #{options[:schema].upcase}") 110 unless aixm.valid? 111 message = "invalid #{options[:schema].upcase} document:\n" + aixm.errors.map(&:message).join("\n") 112 @options[:force] ? warn(message, pry: binding) : fail(message) 113 end 114 end
write_aixm()
click to toggle source
Write the AIXM document.
# File lib/aipp/parser.rb 164 def write_aixm 165 info("Writing #{aixm_file}") 166 AIXM.config.mid = options[:mid] 167 File.write(aixm_file, aixm.to_xml) 168 end
write_build()
click to toggle source
Write the AIXM document and context information.
# File lib/aipp/parser.rb 117 def write_build 118 if @options[:aip] 119 info ("Skipping build") 120 else 121 info("Writing build") 122 builds_path.mkpath 123 build_file = builds_path.join("#{@options[:airac].date.xmlschema}.zip") 124 Dir.mktmpdir do |tmp_dir| 125 tmp_dir = Pathname(tmp_dir) 126 # AIXM/OFMX file 127 AIXM.config.mid = true 128 File.write(tmp_dir.join(aixm_file), aixm.to_xml) 129 # Build details 130 File.write( 131 tmp_dir.join('build.yaml'), { 132 version: AIPP::VERSION, 133 config: @config, 134 options: @options 135 }.to_yaml 136 ) 137 # Manifest 138 manifest, buffer, feature, aip, uid, comment = [], '', '', '', '', '' 139 File.open(tmp_dir.join(aixm_file)).each do |line| 140 buffer << line 141 case line 142 when /^ {2}<(\w{3}).*source=".*?\|.*?\|(.*?)\|/ then buffer, feature, aip = line, $1, $2 143 when /^ {4}<#{feature}Uid[^>]+?mid="(.*?)"/ then uid = $1 144 when /^ {2}<!-- (.*) -->/ then comment = $1 145 when /^ {2}<\/#{feature}>/ 146 manifest << [aip, feature, uid[0,8], AIXM::PayloadHash.new(buffer).to_uuid[0,8], comment].to_csv 147 feature, aip, uid = '', '', '' 148 end 149 end 150 manifest = manifest.sort.prepend "AIP,Feature,Short Uid Hash,Short Feature Hash,Comment\n" 151 File.write(tmp_dir.join('manifest.csv'), manifest.join) 152 # Zip it 153 build_file.delete if build_file.exist? 154 Zip::File.open(build_file, Zip::File::CREATE) do |zip| 155 tmp_dir.children.each do |entry| 156 zip.add(entry.basename.to_s, entry) unless entry.basename.to_s[0] == '.' 157 end 158 end 159 end 160 end 161 end
write_config()
click to toggle source
Write the configuration to config.yml.
# File lib/aipp/parser.rb 171 def write_config 172 info("Writing config.yml") 173 File.write(config_file, config.to_yaml) 174 end
Private Instance Methods
aixm_file()
click to toggle source
# File lib/aipp/parser.rb 178 def aixm_file 179 "#{options[:region]}_#{options[:airac].date.xmlschema}.#{options[:schema]}" 180 end
builds_path()
click to toggle source
# File lib/aipp/parser.rb 182 def builds_path 183 options[:storage].join('builds') 184 end
config_file()
click to toggle source
# File lib/aipp/parser.rb 186 def config_file 187 options[:storage].join('config.yml') 188 end