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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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…

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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.

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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)
[View source]

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