aixm 0.3.3 → 0.3.4
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/.ruby-version +1 -1
 - data/.travis.yml +1 -2
 - data/CHANGELOG.md +20 -0
 - data/README.md +7 -2
 - data/aixm.gemspec +2 -3
 - data/lib/aixm.rb +6 -2
 - data/lib/aixm/a.rb +151 -0
 - data/lib/aixm/component/frequency.rb +2 -2
 - data/lib/aixm/component/geometry.rb +4 -0
 - data/lib/aixm/component/geometry/point.rb +0 -4
 - data/lib/aixm/component/helipad.rb +8 -22
 - data/lib/aixm/component/runway.rb +36 -36
 - data/lib/aixm/component/surface.rb +121 -0
 - data/lib/aixm/component/timetable.rb +1 -0
 - data/lib/aixm/constants.rb +40 -0
 - data/lib/aixm/d.rb +5 -0
 - data/lib/aixm/document.rb +2 -2
 - data/lib/aixm/f.rb +6 -0
 - data/lib/aixm/feature/address.rb +100 -0
 - data/lib/aixm/feature/airport.rb +26 -7
 - data/lib/aixm/feature/airspace.rb +10 -1
 - data/lib/aixm/feature/navigational_aid.rb +1 -1
 - data/lib/aixm/feature/navigational_aid/designated_point.rb +20 -5
 - data/lib/aixm/feature/navigational_aid/dme.rb +2 -2
 - data/lib/aixm/{component → feature}/service.rb +67 -16
 - data/lib/aixm/feature/unit.rb +40 -6
 - data/lib/aixm/refinements.rb +63 -6
 - data/lib/aixm/shortcuts.rb +12 -4
 - data/lib/aixm/version.rb +1 -1
 - data/lib/aixm/xy.rb +6 -1
 - data/lib/aixm/z.rb +6 -0
 - data/schemas/ofmx/0/OFMX-DataTypes.xsd +5 -2
 - data/schemas/ofmx/0/OFMX-Features.xsd +2 -0
 - data/spec/factory.rb +32 -10
 - data/spec/lib/aixm/a_spec.rb +203 -0
 - data/spec/lib/aixm/component/helipad_spec.rb +11 -17
 - data/spec/lib/aixm/component/runway_spec.rb +46 -32
 - data/spec/lib/aixm/component/surface_spec.rb +88 -0
 - data/spec/lib/aixm/d_spec.rb +10 -0
 - data/spec/lib/aixm/document_spec.rb +104 -32
 - data/spec/lib/aixm/f_spec.rb +10 -0
 - data/spec/lib/aixm/feature/address_spec.rb +55 -0
 - data/spec/lib/aixm/feature/airport_spec.rb +73 -3
 - data/spec/lib/aixm/feature/navigational_aid/designated_point_spec.rb +43 -6
 - data/spec/lib/aixm/feature/navigational_aid/dme_spec.rb +2 -2
 - data/spec/lib/aixm/feature/navigational_aid/marker_spec.rb +2 -2
 - data/spec/lib/aixm/feature/navigational_aid/ndb_spec.rb +2 -2
 - data/spec/lib/aixm/feature/navigational_aid/tacan_spec.rb +2 -2
 - data/spec/lib/aixm/feature/navigational_aid/vor_spec.rb +6 -6
 - data/spec/lib/aixm/{component → feature}/service_spec.rb +12 -14
 - data/spec/lib/aixm/feature/unit_spec.rb +7 -4
 - data/spec/lib/aixm/refinements_spec.rb +100 -15
 - data/spec/lib/aixm/z_spec.rb +10 -0
 - metadata +17 -25
 - data/lib/aixm/h.rb +0 -87
 - data/spec/lib/aixm/h_spec.rb +0 -113
 
| 
         @@ -0,0 +1,121 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            using AIXM::Refinements
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module AIXM
         
     | 
| 
      
 4 
     | 
    
         
            +
              class Component
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                # Surface of a runway, helipad etc
         
     | 
| 
      
 7 
     | 
    
         
            +
                #
         
     | 
| 
      
 8 
     | 
    
         
            +
                # ===Cheat Sheet in Pseudo Code:
         
     | 
| 
      
 9 
     | 
    
         
            +
                #   surface = AIXM.surfaceservice(
         
     | 
| 
      
 10 
     | 
    
         
            +
                #     composition: COMPOSITIONS or nil
         
     | 
| 
      
 11 
     | 
    
         
            +
                #     preparation: PREPARATIONS or nil
         
     | 
| 
      
 12 
     | 
    
         
            +
                #     condition: CONDITIONS or nil
         
     | 
| 
      
 13 
     | 
    
         
            +
                #   )
         
     | 
| 
      
 14 
     | 
    
         
            +
                #   surface.pcn = String
         
     | 
| 
      
 15 
     | 
    
         
            +
                #   surface.remarks = String or nil
         
     | 
| 
      
 16 
     | 
    
         
            +
                #
         
     | 
| 
      
 17 
     | 
    
         
            +
                # ===Constants:
         
     | 
| 
      
 18 
     | 
    
         
            +
                # * +AIXM::PCN_RE+ - regular expression to match PCN notations
         
     | 
| 
      
 19 
     | 
    
         
            +
                #
         
     | 
| 
      
 20 
     | 
    
         
            +
                #
         
     | 
| 
      
 21 
     | 
    
         
            +
                # @see https://github.com/openflightmaps/ofmx/wiki/Airport#rwy-runway
         
     | 
| 
      
 22 
     | 
    
         
            +
                class Surface
         
     | 
| 
      
 23 
     | 
    
         
            +
                  COMPOSITIONS = {
         
     | 
| 
      
 24 
     | 
    
         
            +
                    ASPH: :asphalt,
         
     | 
| 
      
 25 
     | 
    
         
            +
                    BITUM: :bitumen,        # dug up, bound and rolled ground
         
     | 
| 
      
 26 
     | 
    
         
            +
                    CONC: :concrete,
         
     | 
| 
      
 27 
     | 
    
         
            +
                    GRADE: :graded_earth,   # graded or rolled earth possibly with some grass
         
     | 
| 
      
 28 
     | 
    
         
            +
                    GRASS: :grass,          # lawn
         
     | 
| 
      
 29 
     | 
    
         
            +
                    GRAVE: :gravel,         # small and midsize rounded stones
         
     | 
| 
      
 30 
     | 
    
         
            +
                    MACADAM: :macadam,      # small rounded stones
         
     | 
| 
      
 31 
     | 
    
         
            +
                    SAND: :sand,
         
     | 
| 
      
 32 
     | 
    
         
            +
                    WATER: :water,
         
     | 
| 
      
 33 
     | 
    
         
            +
                    OTHER: :other           # specify in remarks
         
     | 
| 
      
 34 
     | 
    
         
            +
                  }
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                  PREPARATIONS = {
         
     | 
| 
      
 37 
     | 
    
         
            +
                    AFSC: :aggregate_friction_seal_coat,
         
     | 
| 
      
 38 
     | 
    
         
            +
                    GROOVED: :grooved,      # cut or plastic grooved
         
     | 
| 
      
 39 
     | 
    
         
            +
                    NATURAL: :natural,      # no treatment
         
     | 
| 
      
 40 
     | 
    
         
            +
                    OILED: :oiled,
         
     | 
| 
      
 41 
     | 
    
         
            +
                    PAVED: :paved,
         
     | 
| 
      
 42 
     | 
    
         
            +
                    PFC: :porous_friction_course,
         
     | 
| 
      
 43 
     | 
    
         
            +
                    RFSC: :rubberized_friction_seal_coat,
         
     | 
| 
      
 44 
     | 
    
         
            +
                    ROLLED: :rolled,
         
     | 
| 
      
 45 
     | 
    
         
            +
                    OTHER: :other
         
     | 
| 
      
 46 
     | 
    
         
            +
                  }
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                  CONDITIONS = {
         
     | 
| 
      
 49 
     | 
    
         
            +
                    GOOD: :good,
         
     | 
| 
      
 50 
     | 
    
         
            +
                    FAIR: :fair,
         
     | 
| 
      
 51 
     | 
    
         
            +
                    POOR: :poor,
         
     | 
| 
      
 52 
     | 
    
         
            +
                    OTHER: :other
         
     | 
| 
      
 53 
     | 
    
         
            +
                  }
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                  # @return [Symbol, nil] composition of the surface (see {COMPOSITIONS})
         
     | 
| 
      
 56 
     | 
    
         
            +
                  attr_reader :composition
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                  # @return [Symbol, nil] preparation of the surface (see {PREPARATIONS})
         
     | 
| 
      
 59 
     | 
    
         
            +
                  attr_reader :preparation
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                  # @return [Symbol, nil] condition of the surface (see {CONDITIONS})
         
     | 
| 
      
 62 
     | 
    
         
            +
                  attr_reader :condition
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                  # @return [String, nil] free text remarks
         
     | 
| 
      
 65 
     | 
    
         
            +
                  attr_reader :remarks
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                  def initialize
         
     | 
| 
      
 68 
     | 
    
         
            +
                    @pcn = {}
         
     | 
| 
      
 69 
     | 
    
         
            +
                  end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                  # @return [String]
         
     | 
| 
      
 72 
     | 
    
         
            +
                  def inspect
         
     | 
| 
      
 73 
     | 
    
         
            +
                    %Q(#<#{self.class} composition=#{composition.inspect} preparation=#{preparation.inspect} condition=#{condition.inspect} pcn=#{pcn.inspect}>)
         
     | 
| 
      
 74 
     | 
    
         
            +
                  end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                  def composition=(value)
         
     | 
| 
      
 77 
     | 
    
         
            +
                    @composition = value.nil? ? nil : COMPOSITIONS.lookup(value.to_s.to_sym, nil) || fail(ArgumentError, "invalid composition")
         
     | 
| 
      
 78 
     | 
    
         
            +
                  end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                  def preparation=(value)
         
     | 
| 
      
 81 
     | 
    
         
            +
                    @preparation = value.nil? ? nil : PREPARATIONS.lookup(value.to_s.to_sym, nil) || fail(ArgumentError, "invalid preparation")
         
     | 
| 
      
 82 
     | 
    
         
            +
                  end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                  def condition=(value)
         
     | 
| 
      
 85 
     | 
    
         
            +
                    @condition = value.nil? ? nil : CONDITIONS.lookup(value.to_s.to_sym, nil) || fail(ArgumentError, "invalid condition")
         
     | 
| 
      
 86 
     | 
    
         
            +
                  end
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                  # @return [String, nil] pavement classification number (e.g. "59/F/A/W/T")
         
     | 
| 
      
 89 
     | 
    
         
            +
                  def pcn
         
     | 
| 
      
 90 
     | 
    
         
            +
                    @pcn.none? ? nil : @pcn.values.join("/")
         
     | 
| 
      
 91 
     | 
    
         
            +
                  end
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
                  def pcn=(value)
         
     | 
| 
      
 94 
     | 
    
         
            +
                    return @pcn = {} if value.nil?
         
     | 
| 
      
 95 
     | 
    
         
            +
                    fail(ArgumentError, "invalid PCN") unless match = value.to_s.upcase.match(PCN_RE)
         
     | 
| 
      
 96 
     | 
    
         
            +
                    @pcn = match.named_captures.reject{ |k| k == 'pcn' }
         
     | 
| 
      
 97 
     | 
    
         
            +
                  end
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                  def remarks=(value)
         
     | 
| 
      
 100 
     | 
    
         
            +
                    @remarks = value&.to_s
         
     | 
| 
      
 101 
     | 
    
         
            +
                  end
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
                  # @return [String] AIXM or OFMX markup
         
     | 
| 
      
 104 
     | 
    
         
            +
                  def to_xml
         
     | 
| 
      
 105 
     | 
    
         
            +
                    builder = Builder::XmlMarkup.new(indent: true)
         
     | 
| 
      
 106 
     | 
    
         
            +
                    builder.codeComposition(COMPOSITIONS.key(composition).to_s) if composition
         
     | 
| 
      
 107 
     | 
    
         
            +
                    builder.codePreparation(PREPARATIONS.key(preparation).to_s) if preparation
         
     | 
| 
      
 108 
     | 
    
         
            +
                    builder.codeCondSfc(CONDITIONS.key(condition).to_s) if condition
         
     | 
| 
      
 109 
     | 
    
         
            +
                    if pcn
         
     | 
| 
      
 110 
     | 
    
         
            +
                      builder.valPcnClass(@pcn['capacity'])
         
     | 
| 
      
 111 
     | 
    
         
            +
                      builder.codePcnPavementType(@pcn['type'])
         
     | 
| 
      
 112 
     | 
    
         
            +
                      builder.codePcnPavementSubgrade(@pcn['subgrade'])
         
     | 
| 
      
 113 
     | 
    
         
            +
                      builder.codePcnMaxTirePressure(@pcn['tire_pressure'])
         
     | 
| 
      
 114 
     | 
    
         
            +
                      builder.codePcnEvalMethod(@pcn['evaluation_method'])
         
     | 
| 
      
 115 
     | 
    
         
            +
                    end
         
     | 
| 
      
 116 
     | 
    
         
            +
                    builder.txtPcnNote(@remarks) if remarks
         
     | 
| 
      
 117 
     | 
    
         
            +
                    builder.target!
         
     | 
| 
      
 118 
     | 
    
         
            +
                  end
         
     | 
| 
      
 119 
     | 
    
         
            +
                end
         
     | 
| 
      
 120 
     | 
    
         
            +
              end
         
     | 
| 
      
 121 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,40 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module AIXM
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
              # Characters recognized as symbols for "minute" in DMS notations
         
     | 
| 
      
 4 
     | 
    
         
            +
              MIN = %Q('\u2018\u2019\u00b4).freeze
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              # Characters recognized as symbols for "second" in DMS notations
         
     | 
| 
      
 7 
     | 
    
         
            +
              SEC = %Q("\u201c\u201d\u201f).freeze
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              # Pattern matching geographical coordinates in various DMS notations
         
     | 
| 
      
 10 
     | 
    
         
            +
              DMS_RE = %r(
         
     | 
| 
      
 11 
     | 
    
         
            +
                (?<dms>
         
     | 
| 
      
 12 
     | 
    
         
            +
                  (?<sgn>-)?
         
     | 
| 
      
 13 
     | 
    
         
            +
                  (?<deg>\d{1,3})[° ]{1,2}
         
     | 
| 
      
 14 
     | 
    
         
            +
                  (?<min>\d{2})[#{MIN}#{SEC} ]{1,2}
         
     | 
| 
      
 15 
     | 
    
         
            +
                  (?<sec>\d{2}(?:[\.,]\d{0,2})?)[#{SEC}#{MIN} ]{0,2}
         
     | 
| 
      
 16 
     | 
    
         
            +
                  (?<hem_ne>[NE])?(?<hem_sw>[SW])?
         
     | 
| 
      
 17 
     | 
    
         
            +
                |
         
     | 
| 
      
 18 
     | 
    
         
            +
                  (?<sgn>-)?
         
     | 
| 
      
 19 
     | 
    
         
            +
                  (?<deg>\d{1,3})
         
     | 
| 
      
 20 
     | 
    
         
            +
                  (?<min>\d{2})
         
     | 
| 
      
 21 
     | 
    
         
            +
                  (?<sec>\d{2}(?:[\.,]\d{0,2})?)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  (?:(?<hem_ne>[NE])|(?<hem_sw>[SW]))
         
     | 
| 
      
 23 
     | 
    
         
            +
                )
         
     | 
| 
      
 24 
     | 
    
         
            +
              )xi.freeze
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              # Pattern matching PCN surface strength notations
         
     | 
| 
      
 27 
     | 
    
         
            +
              PCN_RE = %r(
         
     | 
| 
      
 28 
     | 
    
         
            +
                (?<pcn>
         
     | 
| 
      
 29 
     | 
    
         
            +
                  (?<capacity>\d+)\W+
         
     | 
| 
      
 30 
     | 
    
         
            +
                  (?<type>[RF])\W+
         
     | 
| 
      
 31 
     | 
    
         
            +
                  (?<subgrade>[A-D])\W+
         
     | 
| 
      
 32 
     | 
    
         
            +
                  (?<tire_pressure>[W-Z])\W+
         
     | 
| 
      
 33 
     | 
    
         
            +
                  (?<evaluation_method>[TU])
         
     | 
| 
      
 34 
     | 
    
         
            +
                )
         
     | 
| 
      
 35 
     | 
    
         
            +
              )x.freeze
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
              # Pattern matching timetable working hour codes
         
     | 
| 
      
 38 
     | 
    
         
            +
              H_RE = /H(?:24|J|N|X|O)/.freeze
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/aixm/d.rb
    CHANGED
    
    | 
         @@ -8,6 +8,7 @@ module AIXM 
     | 
|
| 
       8 
8 
     | 
    
         
             
              #   AIXM.d(123, :m)
         
     | 
| 
       9 
9 
     | 
    
         
             
              class D
         
     | 
| 
       10 
10 
     | 
    
         
             
                include Comparable
         
     | 
| 
      
 11 
     | 
    
         
            +
                extend Forwardable
         
     | 
| 
       11 
12 
     | 
    
         | 
| 
       12 
13 
     | 
    
         
             
                UNITS = {
         
     | 
| 
       13 
14 
     | 
    
         
             
                  ft: { km: 0.0003048, m: 0.3048, nm: 0.000164578833554 },
         
     | 
| 
         @@ -16,6 +17,10 @@ module AIXM 
     | 
|
| 
       16 
17 
     | 
    
         
             
                  nm: { ft: 6076.11548554, km: 1.852, m: 1852 }
         
     | 
| 
       17 
18 
     | 
    
         
             
                }.freeze
         
     | 
| 
       18 
19 
     | 
    
         | 
| 
      
 20 
     | 
    
         
            +
                # @!method zero?
         
     | 
| 
      
 21 
     | 
    
         
            +
                #   @return [Boolean] whether length is zero
         
     | 
| 
      
 22 
     | 
    
         
            +
                def_delegator :@dist, :zero?
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
       19 
24 
     | 
    
         
             
                # @return [Float] distance
         
     | 
| 
       20 
25 
     | 
    
         
             
                attr_reader :dist
         
     | 
| 
       21 
26 
     | 
    
         | 
    
        data/lib/aixm/document.rb
    CHANGED
    
    | 
         @@ -15,7 +15,7 @@ module AIXM 
     | 
|
| 
       15 
15 
     | 
    
         
             
              #
         
     | 
| 
       16 
16 
     | 
    
         
             
              # @see https://github.com/openflightmaps/ofmx/wiki/Snapshot
         
     | 
| 
       17 
17 
     | 
    
         
             
              class Document
         
     | 
| 
       18 
     | 
    
         
            -
                 
     | 
| 
      
 18 
     | 
    
         
            +
                NAMESPACE_RE = /\A[a-f\d]{8}-[a-f\d]{4}-[a-f\d]{4}-[a-f\d]{4}-[a-f\d]{12}\z/.freeze
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
       20 
20 
     | 
    
         
             
                # @return [String] OFMX region all features in this document belong to
         
     | 
| 
       21 
21 
     | 
    
         
             
                attr_reader :region
         
     | 
| 
         @@ -48,7 +48,7 @@ module AIXM 
     | 
|
| 
       48 
48 
     | 
    
         
             
                end
         
     | 
| 
       49 
49 
     | 
    
         | 
| 
       50 
50 
     | 
    
         
             
                def namespace=(value)
         
     | 
| 
       51 
     | 
    
         
            -
                  fail(ArgumentError, "invalid namespace") unless value.nil? || value.match?( 
     | 
| 
      
 51 
     | 
    
         
            +
                  fail(ArgumentError, "invalid namespace") unless value.nil? || value.match?(NAMESPACE_RE)
         
     | 
| 
       52 
52 
     | 
    
         
             
                  @namespace = value || SecureRandom.uuid
         
     | 
| 
       53 
53 
     | 
    
         
             
                end
         
     | 
| 
       54 
54 
     | 
    
         | 
    
        data/lib/aixm/f.rb
    CHANGED
    
    | 
         @@ -7,8 +7,14 @@ module AIXM 
     | 
|
| 
       7 
7 
     | 
    
         
             
              # @example
         
     | 
| 
       8 
8 
     | 
    
         
             
              #   AIXM.f(123.35, :mhz)
         
     | 
| 
       9 
9 
     | 
    
         
             
              class F
         
     | 
| 
      
 10 
     | 
    
         
            +
                extend Forwardable
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
       10 
12 
     | 
    
         
             
                UNITS = %i(ghz mhz khz).freeze
         
     | 
| 
       11 
13 
     | 
    
         | 
| 
      
 14 
     | 
    
         
            +
                # @!method zero?
         
     | 
| 
      
 15 
     | 
    
         
            +
                #   @return [Boolean] whether frequency is zero
         
     | 
| 
      
 16 
     | 
    
         
            +
                def_delegator :@freq, :zero?
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
       12 
18 
     | 
    
         
             
                # @return [Float] frequency
         
     | 
| 
       13 
19 
     | 
    
         
             
                attr_reader :freq
         
     | 
| 
       14 
20 
     | 
    
         | 
| 
         @@ -0,0 +1,100 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            using AIXM::Refinements
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module AIXM
         
     | 
| 
      
 4 
     | 
    
         
            +
              class Feature
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                # Address or similar means to contact an entity.
         
     | 
| 
      
 7 
     | 
    
         
            +
                #
         
     | 
| 
      
 8 
     | 
    
         
            +
                # ===Cheat Sheet in Pseudo Code:
         
     | 
| 
      
 9 
     | 
    
         
            +
                #   address = AIXM.address(
         
     | 
| 
      
 10 
     | 
    
         
            +
                #     source: String or nil
         
     | 
| 
      
 11 
     | 
    
         
            +
                #     type: TYPES
         
     | 
| 
      
 12 
     | 
    
         
            +
                #     address: String
         
     | 
| 
      
 13 
     | 
    
         
            +
                #   )
         
     | 
| 
      
 14 
     | 
    
         
            +
                #   service.remarks = String or nil
         
     | 
| 
      
 15 
     | 
    
         
            +
                #
         
     | 
| 
      
 16 
     | 
    
         
            +
                # @see https://github.com/openflightmaps/ofmx/wiki/Airport#aha-airport-address
         
     | 
| 
      
 17 
     | 
    
         
            +
                class Address < Feature
         
     | 
| 
      
 18 
     | 
    
         
            +
                  public_class_method :new
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  TYPES = {
         
     | 
| 
      
 21 
     | 
    
         
            +
                    POST: :postal_address,
         
     | 
| 
      
 22 
     | 
    
         
            +
                    PHONE: :phone,
         
     | 
| 
      
 23 
     | 
    
         
            +
                    'PHONE-MET': :weather_phone,
         
     | 
| 
      
 24 
     | 
    
         
            +
                    FAX: :fax,
         
     | 
| 
      
 25 
     | 
    
         
            +
                    TLX: :telex,
         
     | 
| 
      
 26 
     | 
    
         
            +
                    SITA: :sita,
         
     | 
| 
      
 27 
     | 
    
         
            +
                    AFS: :aeronautical_fixed_service_address,
         
     | 
| 
      
 28 
     | 
    
         
            +
                    EMAIL: :email,
         
     | 
| 
      
 29 
     | 
    
         
            +
                    URL: :url,
         
     | 
| 
      
 30 
     | 
    
         
            +
                    'URL-CAM': :webcam,
         
     | 
| 
      
 31 
     | 
    
         
            +
                    'URL-MET': :weather_url,
         
     | 
| 
      
 32 
     | 
    
         
            +
                    RADIO: :radio_frequency,
         
     | 
| 
      
 33 
     | 
    
         
            +
                    OTHER: :other   # specify in remarks
         
     | 
| 
      
 34 
     | 
    
         
            +
                  }
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                  # @return [AIXM::Feature] addressable feature
         
     | 
| 
      
 37 
     | 
    
         
            +
                  attr_reader :addressable
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                  # @return [Symbol] type of address (see {TYPES})
         
     | 
| 
      
 40 
     | 
    
         
            +
                  attr_reader :type
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                  # @return [String] postal address, phone number, radio frequency etc
         
     | 
| 
      
 43 
     | 
    
         
            +
                  attr_reader :address
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                  # @return [String, nil] free text remarks
         
     | 
| 
      
 46 
     | 
    
         
            +
                  attr_reader :remarks
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                  def initialize(source: nil, type:, address:)
         
     | 
| 
      
 49 
     | 
    
         
            +
                    super(source: source)
         
     | 
| 
      
 50 
     | 
    
         
            +
                    self.type, self.address = type, address
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                  # @return [String]
         
     | 
| 
      
 54 
     | 
    
         
            +
                  def inspect
         
     | 
| 
      
 55 
     | 
    
         
            +
                    %Q(#<#{self.class} type=#{type.inspect}>)
         
     | 
| 
      
 56 
     | 
    
         
            +
                  end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                  def addressable=(value)
         
     | 
| 
      
 59 
     | 
    
         
            +
                    fail(ArgumentError, "invalid addressable") unless value.is_a? AIXM::Feature
         
     | 
| 
      
 60 
     | 
    
         
            +
                    @addressable = value
         
     | 
| 
      
 61 
     | 
    
         
            +
                  end
         
     | 
| 
      
 62 
     | 
    
         
            +
                  private :addressable=
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                  def type=(value)
         
     | 
| 
      
 65 
     | 
    
         
            +
                    @type = TYPES.lookup(value&.to_s&.to_sym, nil) || fail(ArgumentError, "invalid type")
         
     | 
| 
      
 66 
     | 
    
         
            +
                  end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                  def address=(value)
         
     | 
| 
      
 69 
     | 
    
         
            +
                    fail(ArgumentError, "invalid address") unless value.is_a? String
         
     | 
| 
      
 70 
     | 
    
         
            +
                    @address = value&.to_s
         
     | 
| 
      
 71 
     | 
    
         
            +
                  end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                  def remarks=(value)
         
     | 
| 
      
 74 
     | 
    
         
            +
                    @remarks = value&.to_s
         
     | 
| 
      
 75 
     | 
    
         
            +
                  end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                  # @return [String] UID markup
         
     | 
| 
      
 78 
     | 
    
         
            +
                  def to_uid(as:, sequence:)
         
     | 
| 
      
 79 
     | 
    
         
            +
                    builder = Builder::XmlMarkup.new(indent: 2)
         
     | 
| 
      
 80 
     | 
    
         
            +
                    builder.tag!(as) do |tag|
         
     | 
| 
      
 81 
     | 
    
         
            +
                      tag << addressable.to_uid.indent(2) if addressable
         
     | 
| 
      
 82 
     | 
    
         
            +
                      tag.codeType(TYPES.key(type).to_s.then { |t| AIXM.aixm? ? t.sub(/-\w+$/, '') : t })
         
     | 
| 
      
 83 
     | 
    
         
            +
                      tag.noSeq(sequence)
         
     | 
| 
      
 84 
     | 
    
         
            +
                    end
         
     | 
| 
      
 85 
     | 
    
         
            +
                  end
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                  # @return [String] AIXM or OFMX markup
         
     | 
| 
      
 88 
     | 
    
         
            +
                  def to_xml(as:, sequence:)
         
     | 
| 
      
 89 
     | 
    
         
            +
                    builder = Builder::XmlMarkup.new(indent: 2)
         
     | 
| 
      
 90 
     | 
    
         
            +
                    builder.comment! ["Address: #{TYPES.key(type)}", addressable&.id].compact.join(' for ')
         
     | 
| 
      
 91 
     | 
    
         
            +
                    builder.tag!(as, { source: (source if AIXM.ofmx?) }.compact) do |tag|
         
     | 
| 
      
 92 
     | 
    
         
            +
                      tag << to_uid(as: :"#{as}Uid", sequence: sequence).indent(2)
         
     | 
| 
      
 93 
     | 
    
         
            +
                      tag.txtAddress(address)
         
     | 
| 
      
 94 
     | 
    
         
            +
                      tag.txtRmk(remarks) if remarks
         
     | 
| 
      
 95 
     | 
    
         
            +
                    end
         
     | 
| 
      
 96 
     | 
    
         
            +
                  end
         
     | 
| 
      
 97 
     | 
    
         
            +
                end
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
              end
         
     | 
| 
      
 100 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/aixm/feature/airport.rb
    CHANGED
    
    | 
         @@ -24,12 +24,13 @@ module AIXM 
     | 
|
| 
       24 
24 
     | 
    
         
             
                #   airport.add_runway(AIXM.runway)
         
     | 
| 
       25 
25 
     | 
    
         
             
                #   airport.add_helipad(AIXM.helipad)
         
     | 
| 
       26 
26 
     | 
    
         
             
                #   airport.add_usage_limitation(UsageLimitation::TYPES)
         
     | 
| 
      
 27 
     | 
    
         
            +
                #   airport.add_address(AIXM.address)
         
     | 
| 
       27 
28 
     | 
    
         
             
                #
         
     | 
| 
       28 
29 
     | 
    
         
             
                # @see https://github.com/openflightmaps/ofmx/wiki/Airport#ahp-airport
         
     | 
| 
       29 
30 
     | 
    
         
             
                class Airport < Feature
         
     | 
| 
       30 
31 
     | 
    
         
             
                  public_class_method :new
         
     | 
| 
       31 
32 
     | 
    
         | 
| 
       32 
     | 
    
         
            -
                   
     | 
| 
      
 33 
     | 
    
         
            +
                  ID_RE = /^([A-Z]{3,4}|[A-Z]{2}[A-Z\d]{4,})$/.freeze
         
     | 
| 
       33 
34 
     | 
    
         | 
| 
       34 
35 
     | 
    
         
             
                  TYPES = {
         
     | 
| 
       35 
36 
     | 
    
         
             
                    AD: :aerodrome,
         
     | 
| 
         @@ -90,10 +91,13 @@ module AIXM 
     | 
|
| 
       90 
91 
     | 
    
         
             
                  # @return [Array<AIXM::Feature::Airport::UsageLimitation>] usage limitations
         
     | 
| 
       91 
92 
     | 
    
         
             
                  attr_accessor :usage_limitations
         
     | 
| 
       92 
93 
     | 
    
         | 
| 
      
 94 
     | 
    
         
            +
                  # @return [Array<AIXM::Feature::Address>] postal address, url, A/A or A/G frequency etc
         
     | 
| 
      
 95 
     | 
    
         
            +
                  attr_reader :addresses
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
       93 
97 
     | 
    
         
             
                  def initialize(source: nil, organisation:, id:, name:, xy:)
         
     | 
| 
       94 
98 
     | 
    
         
             
                    super(source: source)
         
     | 
| 
       95 
99 
     | 
    
         
             
                    self.organisation, self.id, self.name, self.xy = organisation, id, name, xy
         
     | 
| 
       96 
     | 
    
         
            -
                    @runways, @helipads, @usage_limitations = [], [], []
         
     | 
| 
      
 100 
     | 
    
         
            +
                    @runways, @helipads, @usage_limitations, @addresses = [], [], [], []
         
     | 
| 
       97 
101 
     | 
    
         
             
                  end
         
     | 
| 
       98 
102 
     | 
    
         | 
| 
       99 
103 
     | 
    
         
             
                  # @return [String]
         
     | 
| 
         @@ -107,7 +111,7 @@ module AIXM 
     | 
|
| 
       107 
111 
     | 
    
         
             
                  end
         
     | 
| 
       108 
112 
     | 
    
         | 
| 
       109 
113 
     | 
    
         
             
                  def id=(value)
         
     | 
| 
       110 
     | 
    
         
            -
                    fail(ArgumentError, "invalid id `#{id}'") unless value&.upcase&.match?  
     | 
| 
      
 114 
     | 
    
         
            +
                    fail(ArgumentError, "invalid id `#{id}'") unless value&.upcase&.match? ID_RE
         
     | 
| 
       111 
115 
     | 
    
         
             
                    @id = value.upcase
         
     | 
| 
       112 
116 
     | 
    
         
             
                  end
         
     | 
| 
       113 
117 
     | 
    
         | 
| 
         @@ -155,7 +159,7 @@ module AIXM 
     | 
|
| 
       155 
159 
     | 
    
         
             
                  def declination=(value)
         
     | 
| 
       156 
160 
     | 
    
         
             
                    return @declination = value if value.nil?
         
     | 
| 
       157 
161 
     | 
    
         
             
                    fail(ArgumentError, "invalid declination") unless value.is_a?(Numeric) && (-180..180).include?(value)
         
     | 
| 
       158 
     | 
    
         
            -
                    @declination = value.to_f
         
     | 
| 
      
 162 
     | 
    
         
            +
                    @declination = value.to_f + 0   # adding zero prevents -0.0
         
     | 
| 
       159 
163 
     | 
    
         
             
                  end
         
     | 
| 
       160 
164 
     | 
    
         | 
| 
       161 
165 
     | 
    
         
             
                  def transition_z=(value)
         
     | 
| 
         @@ -229,11 +233,22 @@ module AIXM 
     | 
|
| 
       229 
233 
     | 
    
         
             
                    self
         
     | 
| 
       230 
234 
     | 
    
         
             
                  end
         
     | 
| 
       231 
235 
     | 
    
         | 
| 
      
 236 
     | 
    
         
            +
                  # Add an address (postal address, url, A/A or A/G frequency etc) to the airport.
         
     | 
| 
      
 237 
     | 
    
         
            +
                  #
         
     | 
| 
      
 238 
     | 
    
         
            +
                  # @params address [AIXM::Feature::Address] address instance
         
     | 
| 
      
 239 
     | 
    
         
            +
                  # @return [self]
         
     | 
| 
      
 240 
     | 
    
         
            +
                  def add_address(address)
         
     | 
| 
      
 241 
     | 
    
         
            +
                    fail(ArgumentError, "invalid address") unless address.is_a? AIXM::Feature::Address
         
     | 
| 
      
 242 
     | 
    
         
            +
                    address.send(:addressable=, self)
         
     | 
| 
      
 243 
     | 
    
         
            +
                    @addresses << address
         
     | 
| 
      
 244 
     | 
    
         
            +
                    self
         
     | 
| 
      
 245 
     | 
    
         
            +
                  end
         
     | 
| 
      
 246 
     | 
    
         
            +
             
     | 
| 
       232 
247 
     | 
    
         
             
                  # @return [String] UID markup
         
     | 
| 
       233 
     | 
    
         
            -
                  def to_uid
         
     | 
| 
      
 248 
     | 
    
         
            +
                  def to_uid(as: :AhpUid)
         
     | 
| 
       234 
249 
     | 
    
         
             
                    builder = Builder::XmlMarkup.new(indent: 2)
         
     | 
| 
       235 
     | 
    
         
            -
                    builder. 
     | 
| 
       236 
     | 
    
         
            -
                       
     | 
| 
      
 250 
     | 
    
         
            +
                    builder.tag!(as) do |tag|
         
     | 
| 
      
 251 
     | 
    
         
            +
                      tag.codeId(id)
         
     | 
| 
       237 
252 
     | 
    
         
             
                    end
         
     | 
| 
       238 
253 
     | 
    
         
             
                  end
         
     | 
| 
       239 
254 
     | 
    
         | 
| 
         @@ -280,6 +295,10 @@ module AIXM 
     | 
|
| 
       280 
295 
     | 
    
         
             
                        end
         
     | 
| 
       281 
296 
     | 
    
         
             
                      end
         
     | 
| 
       282 
297 
     | 
    
         
             
                    end
         
     | 
| 
      
 298 
     | 
    
         
            +
                    addresses.each.with_object({}) do |address, sequences|
         
     | 
| 
      
 299 
     | 
    
         
            +
                      sequences[address.type] = (sequences[address.type] || 0) + 1
         
     | 
| 
      
 300 
     | 
    
         
            +
                      builder << address.to_xml(as: :Aha, sequence: sequences[address.type])
         
     | 
| 
      
 301 
     | 
    
         
            +
                    end
         
     | 
| 
       283 
302 
     | 
    
         
             
                    builder.target!
         
     | 
| 
       284 
303 
     | 
    
         
             
                  end
         
     | 
| 
       285 
304 
     | 
    
         | 
| 
         @@ -16,6 +16,13 @@ module AIXM 
     | 
|
| 
       16 
16 
     | 
    
         
             
                #   airspace.geometry << AIXM.point or AIXM.arc or AIXM.border or AIXM.circle
         
     | 
| 
       17 
17 
     | 
    
         
             
                #   airspace.layers << AIXM.layer
         
     | 
| 
       18 
18 
     | 
    
         
             
                #
         
     | 
| 
      
 19 
     | 
    
         
            +
                # Some regions define additional airspace types. In LF (France) for
         
     | 
| 
      
 20 
     | 
    
         
            +
                # intance, the types RMZ (radio mandatory zone) and TMZ (transponder
         
     | 
| 
      
 21 
     | 
    
         
            +
                # mandatory zone) exist. Such airspaces are usually specified together
         
     | 
| 
      
 22 
     | 
    
         
            +
                # with a generic type such as +:regulated_airspace+:
         
     | 
| 
      
 23 
     | 
    
         
            +
                #
         
     | 
| 
      
 24 
     | 
    
         
            +
                #   airspace= AIXM.airspace(type: :regulated_airspace, local_type: "RMZ")
         
     | 
| 
      
 25 
     | 
    
         
            +
                #
         
     | 
| 
       19 
26 
     | 
    
         
             
                # @see https://github.com/openflightmaps/ofmx/wiki/Airspace#ase-airspace
         
     | 
| 
       20 
27 
     | 
    
         
             
                class Airspace < Feature
         
     | 
| 
       21 
28 
     | 
    
         
             
                  public_class_method :new
         
     | 
| 
         @@ -71,7 +78,9 @@ module AIXM 
     | 
|
| 
       71 
78 
     | 
    
         
             
                  # @return [Symbol] type of airspace (see {TYPES})
         
     | 
| 
       72 
79 
     | 
    
         
             
                  attr_reader :type
         
     | 
| 
       73 
80 
     | 
    
         | 
| 
       74 
     | 
    
         
            -
                  #  
     | 
| 
      
 81 
     | 
    
         
            +
                  # Some regions define additional types. They are usually specified with
         
     | 
| 
      
 82 
     | 
    
         
            +
                  #
         
     | 
| 
      
 83 
     | 
    
         
            +
                  # @return [String, nil] local type (e.g. "RMZ" or "TMZ")
         
     | 
| 
       75 
84 
     | 
    
         
             
                  attr_reader :local_type
         
     | 
| 
       76 
85 
     | 
    
         | 
| 
       77 
86 
     | 
    
         
             
                  # @return [String, nil] full name (e.g. "LF P 81 CHERBOURG")
         
     | 
| 
         @@ -15,6 +15,7 @@ module AIXM 
     | 
|
| 
       15 
15 
     | 
    
         
             
                  #     xy: AIXM.xy
         
     | 
| 
       16 
16 
     | 
    
         
             
                  #     type: TYPES
         
     | 
| 
       17 
17 
     | 
    
         
             
                  #   )
         
     | 
| 
      
 18 
     | 
    
         
            +
                  #   designated_point.airport = AIXM.airport or nil
         
     | 
| 
       18 
19 
     | 
    
         
             
                  #   designated_point.remarks = String or nil
         
     | 
| 
       19 
20 
     | 
    
         
             
                  #
         
     | 
| 
       20 
21 
     | 
    
         
             
                  # @see https://github.com/openflightmaps/ofmx/wiki/Navigational-aid#dpn-designated-point
         
     | 
| 
         @@ -24,15 +25,23 @@ module AIXM 
     | 
|
| 
       24 
25 
     | 
    
         
             
                    private :organisation
         
     | 
| 
       25 
26 
     | 
    
         | 
| 
       26 
27 
     | 
    
         
             
                    TYPES = {
         
     | 
| 
       27 
     | 
    
         
            -
                      ICAO: :icao, 
     | 
| 
       28 
     | 
    
         
            -
                      ADHP: :adhp, 
     | 
| 
       29 
     | 
    
         
            -
                      COORD: :coordinates, 
     | 
| 
       30 
     | 
    
         
            -
                       
     | 
| 
      
 28 
     | 
    
         
            +
                      ICAO: :icao,                                 # five-letter ICAO id
         
     | 
| 
      
 29 
     | 
    
         
            +
                      ADHP: :adhp,                                 # airport related id
         
     | 
| 
      
 30 
     | 
    
         
            +
                      COORD: :coordinates,                         # derived from geographical coordinates
         
     | 
| 
      
 31 
     | 
    
         
            +
                      'VFR-RP': :vfr_reporting_point,              # usually one or two letter id
         
     | 
| 
      
 32 
     | 
    
         
            +
                      'VFR-MRP': :vfr_mandatory_reporting_point,   # usually one or two letter id
         
     | 
| 
      
 33 
     | 
    
         
            +
                      'VFR-ENR': :vfr_en_route_point,
         
     | 
| 
      
 34 
     | 
    
         
            +
                      'VFR-GLD': :vfr_glider_point,
         
     | 
| 
      
 35 
     | 
    
         
            +
                      OTHER: :other                                # specify in remarks
         
     | 
| 
       31 
36 
     | 
    
         
             
                    }.freeze
         
     | 
| 
       32 
37 
     | 
    
         | 
| 
       33 
38 
     | 
    
         
             
                    # @return [Symbol] type of designated point
         
     | 
| 
       34 
39 
     | 
    
         
             
                    attr_reader :type
         
     | 
| 
       35 
40 
     | 
    
         | 
| 
      
 41 
     | 
    
         
            +
                    # @return [AIXM::Feature::Airport] airport this designated point is
         
     | 
| 
      
 42 
     | 
    
         
            +
                    #   associated with
         
     | 
| 
      
 43 
     | 
    
         
            +
                    attr_reader :airport
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
       36 
45 
     | 
    
         
             
                    def initialize(type:, **arguments)
         
     | 
| 
       37 
46 
     | 
    
         
             
                      super(organisation: false, z: nil, **arguments)
         
     | 
| 
       38 
47 
     | 
    
         
             
                      self.type = type
         
     | 
| 
         @@ -42,6 +51,11 @@ module AIXM 
     | 
|
| 
       42 
51 
     | 
    
         
             
                      @type = TYPES.lookup(value&.to_s&.to_sym, nil) || fail(ArgumentError, "invalid type")
         
     | 
| 
       43 
52 
     | 
    
         
             
                    end
         
     | 
| 
       44 
53 
     | 
    
         | 
| 
      
 54 
     | 
    
         
            +
                    def airport=(value)
         
     | 
| 
      
 55 
     | 
    
         
            +
                      fail(ArgumentError, "invalid airport") unless value.nil? || value.is_a?(AIXM::Feature::Airport)
         
     | 
| 
      
 56 
     | 
    
         
            +
                      @airport = value
         
     | 
| 
      
 57 
     | 
    
         
            +
                    end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
       45 
59 
     | 
    
         
             
                    # @return [String] UID markup
         
     | 
| 
       46 
60 
     | 
    
         
             
                    def to_uid
         
     | 
| 
       47 
61 
     | 
    
         
             
                      builder = Builder::XmlMarkup.new(indent: 2)
         
     | 
| 
         @@ -57,8 +71,9 @@ module AIXM 
     | 
|
| 
       57 
71 
     | 
    
         
             
                      builder = to_builder
         
     | 
| 
       58 
72 
     | 
    
         
             
                      builder.Dpn({ source: (source if AIXM.ofmx?) }.compact) do |dpn|
         
     | 
| 
       59 
73 
     | 
    
         
             
                        dpn << to_uid.indent(2)
         
     | 
| 
      
 74 
     | 
    
         
            +
                        dpn << airport.to_uid(as: :AhpUidAssoc).indent(2) if airport
         
     | 
| 
       60 
75 
     | 
    
         
             
                        dpn.codeDatum('WGE')
         
     | 
| 
       61 
     | 
    
         
            -
                        dpn.codeType(type_key.to_s)
         
     | 
| 
      
 76 
     | 
    
         
            +
                        dpn.codeType(AIXM.aixm? && type_key =~ /^VFR/ ? 'OTHER' : type_key.to_s)
         
     | 
| 
       62 
77 
     | 
    
         
             
                        dpn.txtName(name) if name
         
     | 
| 
       63 
78 
     | 
    
         
             
                        dpn.txtRmk(remarks) if remarks
         
     | 
| 
       64 
79 
     | 
    
         
             
                        dpn.target!
         
     |