Class: AIXM::Document

Inherits:
Object show all
Includes:
Concerns::Association
Defined in:
lib/aixm/document.rb

Overview

The AIXM-Snapshot or OFMX-Snapshot document is the root container for aeronautical information such as airports or airspaces.

Cheat Sheet in Pseudo Code:

document = AIXM.document(
  namespace: String (UUID)
  sourced_at: Time or Date or String or nil
  created_at: Time or Date or String
  effective_at: Time or Date or String
  expiration_at: Time or Date or String or nil
)
document.add_feature(AIXM::Feature)

Constant Summary collapse

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Concerns::Association

included

Constructor Details

#initialize(namespace: nil, sourced_at: nil, created_at: nil, effective_at: nil, expiration_at: nil) ⇒ Document

See the cheat sheet for examples on how to create instances of this class.



75
76
77
78
# File 'lib/aixm/document.rb', line 75

def initialize(namespace: nil, sourced_at: nil, created_at: nil, effective_at: nil, expiration_at: nil)
  self.namespace = namespace
  self.sourced_at, self.created_at, self.effective_at, self.expiration_at = sourced_at, created_at, effective_at, expiration_at
end

Instance Attribute Details

#created_atTime #created_at=(value) ⇒ Object

Creation date and UTC time

Overloads:

  • #created_atTime

    Returns:

    • (Time)
  • #created_at=(value) ⇒ Object

    Parameters:



55
56
57
# File 'lib/aixm/document.rb', line 55

def created_at
  @created_at
end

#effective_atTime #effective_at=(value) ⇒ Object

Effective after date and UTC time

Overloads:

  • #effective_atTime

    Returns:

    • (Time)
  • #effective_at=(value) ⇒ Object

    Parameters:



63
64
65
# File 'lib/aixm/document.rb', line 63

def effective_at
  @effective_at
end

#expiration_atTime? #expiration_at=(value) ⇒ Object

Expiration after date and UTC time

Overloads:

  • #expiration_atTime?

    Returns:

    • (Time, nil)
  • #expiration_at=(value) ⇒ Object

    Parameters:

    • value (Time, nil)


71
72
73
# File 'lib/aixm/document.rb', line 71

def expiration_at
  @expiration_at
end

#namespaceString #namespace=(value) ⇒ Object

UUID to namespace the data contained in this document

Overloads:

  • #namespaceString

    Returns:

    • (String)
  • #namespace=(value) ⇒ Object

    Parameters:

    • value (String)


39
40
41
# File 'lib/aixm/document.rb', line 39

def namespace
  @namespace
end

#sourced_atTime #sourced_at=(value) ⇒ Object

Last upstream source data update date and UTC time

Overloads:

  • #sourced_atTime

    Returns:

    • (Time)
  • #sourced_at=(value) ⇒ Object

    Parameters:

    • value (Time, nil)


47
48
49
# File 'lib/aixm/document.rb', line 47

def sourced_at
  @sourced_at
end

Instance Method Details

#add_feature(feature) ⇒ self

Parameters:

Returns:

  • (self)


31
# File 'lib/aixm/document.rb', line 31

has_many :features, accept: ['AIXM::Feature']

#documentNokogiri::XML::Document

Returns Nokogiri AIXM or OFMX document.

Returns:

  • (Nokogiri::XML::Document)

    Nokogiri AIXM or OFMX document



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/aixm/document.rb', line 170

def document
  meta = {
    'xmlns:xsi': AIXM.schema(:namespace),
    version: AIXM.schema(:version),
    origin: "rubygem aixm-#{AIXM::VERSION}",
    namespace: (namespace if AIXM.ofmx?),
    regions: (regions.join(' '.freeze) if AIXM.ofmx?),
    sourced: (@sourced_at&.utc&.xmlschema if AIXM.ofmx?),
    created: @created_at.utc.xmlschema,
    effective: @effective_at.utc.xmlschema,
    expiration: (@expiration_at&.utc&.xmlschema if AIXM.ofmx?)
  }.compact
  Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |builder|
    builder.send(AIXM.schema(:root), meta) do |root|
      root.text("\n")
      AIXM::Concerns::Memoize.method :to_uid do
        # TODO: indent is lost if added directly to the builder
        # features.each { _1.add_to(root) }
        features.each { root << _1.to_xml.indent(2) }
      end
      if AIXM.ofmx? && AIXM.config.mid
        AIXM::PayloadHash::Mid.new(builder.doc).insert_mid
      end
    end
  end.doc
end

#errorsArray<String>

Validate the generated AIXM or OFMX against its XSD and return the errors found.

Returns:

  • (Array<String>)

    validation errors



162
163
164
165
166
167
# File 'lib/aixm/document.rb', line 162

def errors
  xsd = Nokogiri::XML::Schema(File.open(AIXM.schema(:xsd)))
  xsd.validate(Nokogiri::XML(to_xml)).reject do |error|
    AIXM.config.ignored_errors && error.message.match?(AIXM.config.ignored_errors)
  end
end

#featuresArray<AIXM::Feature>

Returns features (e.g. airport or airspace) present in this document.

Returns:



31
# File 'lib/aixm/document.rb', line 31

has_many :features, accept: ['AIXM::Feature']

#group_obstacles!(max_distance: AIXM.d(1, :nm)) ⇒ Integer

Note:

OFMX requires every obstacle, even single ones, to be part of an obstacle group which has a region assigned. For this to work, you must assure every obstacle has a region assigned when using this method.

Compare all ungrouped obstacles and create new obstacle groups whose members are located within max_distance pairwise.

Parameters:

  • max_distance (AIXM::D) (defaults to: AIXM.d(1, :nm))

    max distance between obstacle group member pairs (default: 1 NM)

Returns:

  • (Integer)

    number of obstacle groups added



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/aixm/document.rb', line 134

def group_obstacles!(max_distance: AIXM.d(1, :nm))
  obstacles, list = features.find_by(:obstacle), {}
  while subject = obstacles.send(:shift)
    obstacles.each do |obstacle|
      if subject.xy.distance(obstacle.xy) <= max_distance
        [subject, obstacle].each { list[_1] = list[subject] || SecureRandom.uuid }
      end
    end
  end
  list.group_by(&:last).each do |_, grouped_list|
    first_obstacle = grouped_list.first.first
    obstacle_group = AIXM.obstacle_group(source: first_obstacle.source, region: first_obstacle.region)
    grouped_list.each { |o, _| obstacle_group.add_obstacle features.send(:delete, o) }
    add_feature obstacle_group
  end.count
end

#inspectString

Returns:

  • (String)


81
82
83
# File 'lib/aixm/document.rb', line 81

def inspect
  %Q(#<#{self.class} created_at=#{created_at.inspect}>)
end

#regionsArray<String>

Regions used throughout this document.

Returns:

  • (Array<String>)

    white space separated list of region codes



120
121
122
# File 'lib/aixm/document.rb', line 120

def regions
  features.map(&:region).uniq.sort
end

#to_xmlString

Returns AIXM or OFMX markup.

Returns:

  • (String)

    AIXM or OFMX markup



198
199
200
# File 'lib/aixm/document.rb', line 198

def to_xml
  document.to_xml
end

#valid?Boolean

Validate the generated AIXM or OFMX against its XSD.

Returns:

  • (Boolean)

    whether valid or not



154
155
156
# File 'lib/aixm/document.rb', line 154

def valid?
  errors.none?
end