Class: Distribution

Inherits:
Object
  • Object
show all
Defined in:
lib/distribution.rb

Overview

An array of OTU distributions

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source_object_types: [ :asserted_distribution, :collecting_event_geographic_area, :collecting_event_georeference], otus: [], preferred_georeference_only: false) ⇒ Distribution

Returns a new instance of Distribution.



24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/distribution.rb', line 24

def initialize(
  source_object_types: [
    :asserted_distribution,
    :collecting_event_geographic_area,
    :collecting_event_georeference],
  otus: [],
  preferred_georeference_only: false # does nothing at present
)
  @preferred_georeference_only = preferred_georeference_only
  @source_object_types         = source_object_types
  @otus                        = otus
end

Instance Attribute Details

#map_source_objects ⇒ Hash

Returns:

  • (Hash)


13
14
15
# File 'lib/distribution.rb', line 13

def map_source_objects
  @map_source_objects
end

#otus ⇒ Object

the list of OTUs to generate distributions for



20
21
22
# File 'lib/distribution.rb', line 20

def otus
  @otus
end

#preferred_georeference_only ⇒ Object

Returns the value of attribute preferred_georeference_only.



22
23
24
# File 'lib/distribution.rb', line 22

def preferred_georeference_only
  @preferred_georeference_only
end

#source_object_types ⇒ Object

A parameter that indicates which types of data should be extracted for the list of OTUs provided [ asserted_distribution, :collecting_event_geographic_area, :collecting_event_georeference ]



17
18
19
# File 'lib/distribution.rb', line 17

def source_object_types
  @source_object_types
end

Instance Method Details

#asserted_distribution_properties(json, asserted_distribution, data) ⇒ JSON

Parameters:

Returns:

  • (JSON)


188
189
190
191
192
193
# File 'lib/distribution.rb', line 188

def asserted_distribution_properties(json, asserted_distribution, data)
  json['properties']['label'] =
    asserted_distribution.asserted_distribution_shape.name
  json['properties']['metadata'][asserted_distribution.asserted_distribution_shape_type] = asserted_distribution.asserted_distribution_shape.attributes
  json['properties']['metadata']['Source'] = asserted_distribution.source.attributes if asserted_distribution.source
end

#build_map_source_objects ⇒ Hash

Returns:

  • (Hash)


43
44
45
46
47
48
49
50
51
52
# File 'lib/distribution.rb', line 43

def build_map_source_objects
  @map_source_objects = {} if @map_source_objects.nil?
  otus.each do |o|
    @map_source_objects[o.id] = []
    source_object_types.each do |t|
      insert_source_objects(o, t)
    end
  end
  @map_source_objects
end

#collecting_event_geographic_area_properties(json, collecting_event, data) ⇒ JSON

Parameters:

Returns:

  • (JSON)


199
200
201
202
# File 'lib/distribution.rb', line 199

def collecting_event_geographic_area_properties(json, collecting_event, data)
  json['properties']['label'] = collecting_event.geographic_area.name
  json['properties']['metadata']['GeographicArea'] = collecting_event.geographic_area.attributes
end

#collecting_event_georeference_properties(json, georeference, data) ⇒ JSON

Parameters:

Returns:

  • (JSON)


208
209
210
# File 'lib/distribution.rb', line 208

def collecting_event_georeference_properties(json, georeference, data)
  json['properties']['label'] = "Collecting event #{data.id}."
end

#geographic_item_for_collecting_event_geographic_area(collecting_event) ⇒ GeographicItem?

Parameters:

Returns:



100
101
102
# File 'lib/distribution.rb', line 100

def geographic_item_for_collecting_event_geographic_area(collecting_event)
  collecting_event.geographic_area.geographic_items.first
end

#geographic_item_for_collecting_event_georeference(collecting_event) ⇒ GeographicItem?

Parameters:

Returns:



106
107
108
# File 'lib/distribution.rb', line 106

def geographic_item_for_collecting_event_georeference(collecting_event)
  asserted_distribution.geographic_area.geographic_items.first
end

#get_data_for_asserted_distributions(otu) ⇒ Scope

Parameters:

Returns:

  • (Scope)


112
113
114
# File 'lib/distribution.rb', line 112

def get_data_for_asserted_distributions(otu)
  otu.asserted_distributions # .where(geographic_area has a shape clause)
end

#get_data_for_collecting_event_geographic_areas(otu) ⇒ Scope

have a better has_many method for this I think

Parameters:

Returns:

  • (Scope)


119
120
121
# File 'lib/distribution.rb', line 119

def get_data_for_collecting_event_geographic_areas(otu)
  otu.collecting_events.joins(geographic_area: [:geographic_items])
end

#get_data_for_collecting_event_georeferences(otu) ⇒ Array

Parameters:

Returns:

  • (Array)


125
126
127
# File 'lib/distribution.rb', line 125

def get_data_for_collecting_event_georeferences(otu)
  [otu]
end

#insert_for_asserted_distribution(otu, source, type) ⇒ Array

json insert necessary

Parameters:

Returns:

  • (Array)


68
69
70
# File 'lib/distribution.rb', line 68

def insert_for_asserted_distribution(otu, source, type)
  insert_source_object(otu, source, source.asserted_distribution_shape, type)
end

#insert_for_collecting_event_geographic_area(otu, source, type) ⇒ Array

Parameters:

Returns:

  • (Array)


76
77
78
# File 'lib/distribution.rb', line 76

def insert_for_collecting_event_geographic_area(otu, source, type)
  insert_source_object(otu, source, source.geographic_area, type)
end

#insert_for_collecting_event_georeference(otu, source, type) ⇒ Object

Parameters:



83
84
85
86
87
88
# File 'lib/distribution.rb', line 83

def insert_for_collecting_event_georeference(otu, source, type)
  georeferences = (preferred_georeference_only ? [source.georeferences.first] : source.georeferences)
  georeferences.each do |g|
    insert_source_object(otu, source, g, type)
  end
end

#insert_source_object(otu, source, data, type) ⇒ Object

Parameters:

  • otu (Otu)
  • source (Source)
  • data (Object)
  • type (String)


94
95
96
# File 'lib/distribution.rb', line 94

def insert_source_object(otu, source, data, type)
  @map_source_objects[otu.id].push([source, data, type])
end

#insert_source_objects(otu, type) ⇒ Object

Parameters:

  • otu (Otu)
  • type (String)


56
57
58
59
60
61
# File 'lib/distribution.rb', line 56

def insert_source_objects(otu, type)
  records_with_data = self.send("get_data_for_#{type}s", otu) # all returned data must have geographic_item at this point
  records_with_data.each do |r|
    self.send("insert_for_#{type}", otu, r, type)
  end
end

#to_json ⇒ JSON

rubocop:disable Metrics/MethodLength rubocop:disable Style/StringHashKeys

Returns:

  • (JSON)


132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
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/distribution.rb', line 132

def to_json
  result = {
    'otu_ids' => map_source_objects.keys
  }

  i = 1
  j = 0
  map_source_objects.each_key do |otu_id|
    feature_collection = {
      'type'     => 'FeatureCollection',
      'features' => []
    }
    colors             = [
      ['black', 0x000000], ['blue', 0x000088], ['orange', 0xDD6600], ['green', 0x008800], ['red', 0x880000],
      ['purple', 0x880088], ['yellow', 0xAAAA55], ['brown', 0x664400], ['gray', 0x666666],
      ['white', 0xFFFFFF], ['shadow', 0x888888]]
    opacities          = {'asserted_distribution' => 0.66, 'collecting_event_georeference' => 0.44, 'collecting_event_geographic_area' => 0.22}
    map_source_objects[otu_id].each do |source, data, type|
      source_class = source.class.name
      route_base   = source.class.table_name

      color_index = (j + 1) % 8 # only 8 colors, excluding black and white (mousover color)
      color_name  = colors[color_index][0]
      color       = sprintf('#%06X', colors[color_index][1])

      json = data.to_simple_json_feature
      json['properties'].merge!(
        'id'          => i,
        'source'      => source_class,
        'source_type' => type.to_s,
        'metadata'    => {source_class => source.attributes},
        'api'         => {
          'concise_details'  => "/#{route_base}/#{data.id}/concise_details",
          'expanded_details' => "/#{route_base}/#{data.id}/expanded_details"
        },
        'colorName'   => color_name,
        'fillColor'   => color,
        'fillOpacity' => opacities[type.to_s]
      )

      send("#{type}_properties", json, source, data)

      feature_collection['features'].push(json)
      i = i + 1
    end
    j = j + 1
    result.merge!(otu_id => feature_collection)
  end
  result
end