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)
  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, created_at: nil, effective_at: nil, expiration_at: nil) ⇒ Document

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



66
67
68
69
# File 'lib/aixm/document.rb', line 66

def initialize(namespace: nil, created_at: nil, effective_at: nil, expiration_at: nil)
  self.namespace = namespace
  self.created_at, self.effective_at, self.expiration_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:



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

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:



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

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)


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

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)


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

def namespace
  @namespace
end

Instance Method Details

#add_feature(feature) ⇒ self

Parameters:

Returns:

  • (self)


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

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

#documentNokogiri::XML::Document

Returns Nokogiri AIXM or OFMX document.

Returns:

  • (Nokogiri::XML::Document)

    Nokogiri AIXM or OFMX document



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/aixm/document.rb', line 157

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?),
    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



149
150
151
152
153
154
# File 'lib/aixm/document.rb', line 149

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:



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

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



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/aixm/document.rb', line 121

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)


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

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



107
108
109
# File 'lib/aixm/document.rb', line 107

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

#to_xmlString

Returns AIXM or OFMX markup.

Returns:

  • (String)

    AIXM or OFMX markup



184
185
186
# File 'lib/aixm/document.rb', line 184

def to_xml
  document.to_xml
end

#valid?Boolean

Validate the generated AIXM or OFMX against its XSD.

Returns:

  • (Boolean)

    whether valid or not



141
142
143
# File 'lib/aixm/document.rb', line 141

def valid?
  errors.none?
end