Module: Shared::Dwc::CollectingEventExtensions

Extended by:
ActiveSupport::Concern
Included in:
CollectionObject::DwcExtensions, FieldOccurrence::DwcExtensions
Defined in:
app/models/concerns/shared/dwc/collecting_event_extensions.rb

Overview

Shared code for data classes that can be indexed/serialized as DwcOccurrence records

Instance Method Summary collapse

Instance Method Details

#dwc_coordinate_uncertainty_in_metersObject

TODO: extend to Georeferences when we understand how to describe spatial uncertainty



98
99
100
101
102
103
104
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 98

def dwc_coordinate_uncertainty_in_meters
  if georeference_attributes[:coordinateUncertaintyInMeters]
    georeference_attributes[:coordinateUncertaintyInMeters]
  else
    collecting_event&.verbatim_geolocation_uncertainty
  end
end

#dwc_countryObject



219
220
221
222
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 219

def dwc_country
  v = try(:collecting_event).try(:geographic_names)
  v[:country] if v
end

#dwc_countyObject



229
230
231
232
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 229

def dwc_county
  v = try(:collecting_event).try(:geographic_names)
  v[:county] if v
end

#dwc_dayObject



292
293
294
295
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 292

def dwc_day
  return unless collecting_event
  collecting_event.start_date_day.presence
end

#dwc_decimal_latitudeObject



238
239
240
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 238

def dwc_decimal_latitude
  georeference_attributes[:decimalLatitude]
end

#dwc_decimal_longitudeObject



242
243
244
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 242

def dwc_decimal_longitude
  georeference_attributes[:decimalLongitude]
end

#dwc_end_day_of_yearObject



302
303
304
305
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 302

def dwc_end_day_of_year
  return unless collecting_event
  collecting_event.end_day_of_year.presence
end

#dwc_event_dateObject



267
268
269
270
271
272
273
274
275
276
277
278
279
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 267

def dwc_event_date
  return unless collecting_event
  return if collecting_event.start_date_year.blank? # don't need to check end, it requires start in model

  %w{start_date end_date}
    .map { |d| %w{year month day}
    .map { |p| collecting_event["#{d}_#{p}"] }
    .map { |p| '%02d' % p if p } # At least two digits
    }
      .map { |d| d.compact.join('-') }
      .reject(&:blank?)
      .join('/').presence
end

#dwc_event_idObject



120
121
122
123
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 120

def dwc_event_id
  return nil unless collecting_event
  collecting_event.identifiers.where(type: 'Identifier::Local::Event').first&.cached.presence
end

#dwc_event_remarksObject



59
60
61
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 59

def dwc_event_remarks
  collecting_event&.notes&.collect {|n| n.text}&.join(CollectionObject::DWC_DELIMITER).presence
end

#dwc_event_timeObject



250
251
252
253
254
255
256
257
258
259
260
261
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 250

def dwc_event_time
  return unless collecting_event

  %w{start_time end_time}
    .map { |t| %w{hour minute second}
    .map { |p| collecting_event["#{t}_#{p}"] }
    .map { |p| '%02d' % p if p } # At least two digits
    }
      .map { |t| t.compact.join(':') }
      .reject(&:blank?)
      .join('/').presence
end

#dwc_field_numberObject

Prioritize the formalized version of the identifier for data-sharing purposes



115
116
117
118
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 115

def dwc_field_number
  return nil unless collecting_event
  collecting_event.identifiers.where(type: 'Identifier::Local::FieldNumber').first&.cached || collecting_event&.verbatim_field_number
end

#dwc_footprint_wktObject



71
72
73
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 71

def dwc_footprint_wkt
  georeference_attributes[:footprintWKT]
end

#dwc_geodetic_datumObject



83
84
85
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 83

def dwc_geodetic_datum
  georeference_attributes[:geodeticDatum]
end

#dwc_georeference_protocolObject



307
308
309
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 307

def dwc_georeference_protocol
  georeference_attributes[:georeferenceProtocol]
end

#dwc_georeference_remarksObject



67
68
69
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 67

def dwc_georeference_remarks
  georeference_attributes[:georeferenceRemarks]
end

#dwc_georeference_sourcesObject



63
64
65
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 63

def dwc_georeference_sources
  georeference_attributes[:georeferenceSources]
end

#dwc_georeferenced_byObject



75
76
77
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 75

def dwc_georeferenced_by
  georeference_attributes[:georeferencedBy]
end

#dwc_georeferenced_dateObject

georeferenceDate technically could look at papertrail to see when geographic_area_id appeared



93
94
95
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 93

def dwc_georeferenced_date
  georeference_attributes[:georeferencedDate]
end

#dwc_internal_attribute_for(target = :collection_object, dwc_term_name) ⇒ Object

TODO: hmm…



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 126

def dwc_internal_attribute_for(target = :collection_object, dwc_term_name)
  return nil if dwc_term_name.nil?

  case target
  when  :collecting_event
    return nil unless collecting_event
    collecting_event.internal_attributes.includes(:predicate)
      .where(
        controlled_vocabulary_terms: {uri: ::DWC_ATTRIBUTE_URIS[dwc_term_name.to_sym] })
      .pluck(:value)&.join(', ').presence
  when :collection_object
    internal_attributes.includes(:predicate)
      .where(
        controlled_vocabulary_terms: {uri: ::DWC_ATTRIBUTE_URIS[dwc_term_name.to_sym] })
      .pluck(:value)&.join(', ').presence
  else
    nil
  end
end

#dwc_localityObject



234
235
236
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 234

def dwc_locality
  collecting_event.try(:verbatim_locality)
end

#dwc_maximum_depth_in_metersObject



154
155
156
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 154

def dwc_maximum_depth_in_meters
  dwc_internal_attribute_for(:collecting_event, :maximumDepthInMeters)
end

#dwc_maximum_elevation_in_metersObject



171
172
173
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 171

def dwc_maximum_elevation_in_meters
  collecting_event&.maximum_elevation
end

#dwc_minimum_depth_in_metersObject



150
151
152
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 150

def dwc_minimum_depth_in_meters
  dwc_internal_attribute_for(:collecting_event, :minimumDepthInMeters)
end

#dwc_minimum_elevation_in_metersObject



175
176
177
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 175

def dwc_minimum_elevation_in_meters
  collecting_event&.minimum_elevation
end

#dwc_monthObject



286
287
288
289
290
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 286

def dwc_month
  return unless collecting_event
  return if collecting_event.start_date_month.present? && collecting_event.end_date_month.present?
  collecting_event.start_date_month.presence
end

#dwc_recorded_byObject

Definition: A list (concatenated and separated) of names of people, groups, or organizations responsible for recording the original Occurrence. The primary collector or observer, especially one who applies a personal identifier (recordNumber), should be listed first.

This was interpreted as collectors (in the field in this context), not those who recorded other aspects of the data.



206
207
208
209
210
211
212
213
214
215
216
217
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 206

def dwc_recorded_by
  v = nil
  if collecting_event
    v = collecting_event.collectors
      .order('roles.position')
      .map(&:name)
      .join(CollectionObject::DWC_DELIMITER)
      .presence
    v = collecting_event.verbatim_collectors.presence if v.blank?
  end
  v
end

#dwc_recorded_by_idObject

See dwc_recorded_by TODO: Expand to any GlobalIdentifier



190
191
192
193
194
195
196
197
198
199
200
201
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 190

def dwc_recorded_by_id
  if collecting_event
    collecting_event.collectors
      .joins(:identifiers)
      .where(identifiers: {type: ['Identifier::Global::Orcid', 'Identifier::Global::Wikidata']})
      .select('identifiers.identifier_object_id, identifiers.cached')
      .unscope(:order)
      .distinct
      .pluck('identifiers.cached')
      .join(CollectionObject::DWC_DELIMITER)&.presence
  end
end

#dwc_sampling_protocolObject

TODO: Reconcile with Protocol (capital P) assignments



180
181
182
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 180

def dwc_sampling_protocol
  collecting_event&.verbatim_method
end

#dwc_start_day_of_yearObject



297
298
299
300
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 297

def dwc_start_day_of_year
  return unless collecting_event
  collecting_event.start_day_of_year.presence
end

#dwc_state_provinceObject



224
225
226
227
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 224

def dwc_state_province
  v = try(:collecting_event).try(:geographic_names)
  v[:state] if v
end

#dwc_verbatim_coordinatesObject



162
163
164
165
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 162

def dwc_verbatim_coordinates
  return nil unless collecting_event
  [collecting_event.verbatim_latitude, collecting_event.verbatim_longitude].compact.join(' ').presence
end

#dwc_verbatim_depthObject



158
159
160
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 158

def dwc_verbatim_depth
  dwc_internal_attribute_for(:collecting_event, :verbatimDepth)
end

#dwc_verbatim_elevationObject



167
168
169
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 167

def dwc_verbatim_elevation
  collecting_event&.verbatim_elevation
end

#dwc_verbatim_event_dateObject



263
264
265
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 263

def dwc_verbatim_event_date
  collecting_event&.verbatim_date
end

#dwc_verbatim_habitatObject



184
185
186
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 184

def dwc_verbatim_habitat
  collecting_event&.verbatim_habitat
end

#dwc_verbatim_latitudeObject



106
107
108
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 106

def dwc_verbatim_latitude
  collecting_event&.verbatim_latitude
end

#dwc_verbatim_localityObject



246
247
248
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 246

def dwc_verbatim_locality
  collecting_event.try(:verbatim_locality)
end

#dwc_verbatim_longitudeObject



110
111
112
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 110

def dwc_verbatim_longitude
  collecting_event&.verbatim_longitude
end

#dwc_verbatim_srsObject



87
88
89
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 87

def dwc_verbatim_srs
  georeference_attributes[:dwcVerbatimSrs]
end

#dwc_water_bodyObject



146
147
148
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 146

def dwc_water_body
  dwc_internal_attribute_for(:collecting_event, :waterBody)
end

#dwc_yearObject



281
282
283
284
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 281

def dwc_year
  return unless collecting_event
  collecting_event.start_date_year.presence
end

#set_georeference_attributesHash

TODO: Revisit

Returns:

  • (Hash)


24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'app/models/concerns/shared/dwc/collecting_event_extensions.rb', line 24

def set_georeference_attributes
  case collecting_event&.dwc_georeference_source
  when :georeference
    collecting_event.preferred_georeference.dwc_georeference_attributes
  when :verbatim
    h = collecting_event.dwc_georeference_attributes

    # Our interpretation is now that georeferencedBy is the person who "computed" the
    # values, not transcribed the values.
    #
    #     if a = collecting_event&.attribute_updater(:verbatim_latitude)
    #       h[:georeferencedBy] = User.find(a).name
    #     end

    # verbatim_longitude could technically be different, but...
    h[:georeferencedDate] = (collecting_event.attribute_updated(:verbatim_latitude) if collecting_event.verbatim_latitude)

    h

  when :geographic_area
    h = collecting_event.geographic_area.dwc_georeference_attributes

    if collecting_event.geographic_area_id && (a = collecting_event.attribute_updater(:geographic_area_id))
      h[:georeferencedBy] = User.find_by(id: a)&.name # User might have been deleted if coming from PaperTrail versioning
    end

    h[:georeferencedDate] = (collecting_event.attribute_updated(:geographic_area_id) if collecting_event.geographic_area_id)

    h
  else
    {}
  end
end