Class: Queries::AssertedDistribution::Filter

Inherits:
Query::Filter show all
Includes:
Concerns::Citations, Concerns::DataAttributes, Concerns::Notes, Concerns::Tags
Defined in:
lib/queries/asserted_distribution/filter.rb

Constant Summary collapse

PARAMS =
[
  :asserted_distribution_id,
  :descendants,
  :geo_json,
  :geographic_area_id,
  :geographic_item_id,
  :geographic_area_mode,
  :otu_id,
  :presence,
  :radius,
  :taxon_name_id,
  :wkt,
  asserted_distribution_id: [],
  geographic_area_id: [],
  geographic_item_id: [],
  otu_id: [],
  taxon_name_id: [],
].freeze

Constants inherited from Query::Filter

Query::Filter::FILTER_QUERIES, Query::Filter::SUBQUERIES

Instance Attribute Summary collapse

Attributes inherited from Query::Filter

#api, #asserted_distribution_query, #biological_association_query, #biological_associations_graph_query, #collecting_event_query, #collection_object_query, #content_query, #controlled_vocabulary_term_query, #data_attribute_query, #descriptor_query, #extract_query, #field_occurrence_query, #image_query, #loan_query, #object_global_id, #observation_query, #otu_query, #page, #paginate, #params, #per, #person_query, #project_id, #recent, #taxon_name_query

Attributes inherited from Query

#query_string, #terms

Instance Method Summary collapse

Methods inherited from Query::Filter

#all, #all_and_clauses, #all_merge_clauses, #annotator_and_clauses, #annotator_merge_clauses, annotator_params, api_except_params, api_excluded_params, #attribute_exact_facet, base_filter, #deep_permit, included_annotator_facets, inverted_subqueries, #model_id_facet, #object_global_id_facet, params, #permitted_params, #project_id_facet, query_name, #query_name, #set_nested_queries, #shared_and_clauses, #subquery_vector

Methods inherited from Query

#alphabetic_strings, #alphanumeric_strings, base_name, #base_name, #base_query, #build_terms, #cached_facet, #end_wildcard, #levenshtein_distance, #match_ordered_wildcard_pieces_in_cached, #no_terms?, referenced_klass, #referenced_klass, #referenced_klass_except, #referenced_klass_intersection, #referenced_klass_union, #start_and_end_wildcard, #start_wildcard, #table, #wildcard_pieces

Constructor Details

#initialize(query_params) ⇒ Filter

Returns a new instance of Filter.



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/queries/asserted_distribution/filter.rb', line 77

def initialize(query_params)
  super
  @asserted_distribution_id = params[:asserted_distribution_id]
  @descendants = boolean_param(params, :descendants)
  @geo_json = params[:geo_json]
  @geographic_area_id = params[:geographic_area_id]
  @geographic_item_id = params[:geographic_item_id]
  @geographic_area_mode = boolean_param(params, :geographic_area_mode)
  @geographic_area_mode = boolean_param(params, :geographic_area_mode)
  @otu_id = params[:otu_id]
  @presence = boolean_param(params, :presence)
  @radius = params[:radius].presence || 100.0
  @taxon_name_id = params[:taxon_name_id]
  @wkt = params[:wkt]

  set_citations_params(params)
  set_data_attributes_params(params)
  set_notes_params(params)
  set_tags_params(params)
end

Instance Attribute Details

#asserted_distribution_idArray

Parameters:

  • asserted_distribution_id (Array, Integer, String)

Returns:

  • (Array)


32
33
34
# File 'lib/queries/asserted_distribution/filter.rb', line 32

def asserted_distribution_id
  @asserted_distribution_id
end

#descendantsBoolean?

Returns true - include descendants of taxon_name_id in scope false, nil - only exact matches.

Returns:

  • (Boolean, nil)

    true - include descendants of taxon_name_id in scope false, nil - only exact matches



71
72
73
# File 'lib/queries/asserted_distribution/filter.rb', line 71

def descendants
  @descendants
end

#geo_jsonObject

Returns the value of attribute geo_json.



55
56
57
# File 'lib/queries/asserted_distribution/filter.rb', line 55

def geo_json
  @geo_json
end

#geographic_area_idArray

Parameters:

  • geographic_area_id (Array, Integer, String)

Returns:

  • (Array)


40
41
42
# File 'lib/queries/asserted_distribution/filter.rb', line 40

def geographic_area_id
  @geographic_area_id
end

#geographic_area_modeBoolean?

Returns How to treat GeographicAreas

nil - non-spatial match by only those records matching the geographic_area_id exactly
true - spatial match
false - non-spatial match (descendants).

Returns:

  • (Boolean, nil)

    How to treat GeographicAreas

    nil - non-spatial match by only those records matching the geographic_area_id exactly
    true - spatial match
    false - non-spatial match (descendants)
    


51
52
53
# File 'lib/queries/asserted_distribution/filter.rb', line 51

def geographic_area_mode
  @geographic_area_mode
end

#geographic_item_idArray

Parameters:

  • geographic_item_id (Array, Integer, String)

Returns:

  • (Array)


44
45
46
# File 'lib/queries/asserted_distribution/filter.rb', line 44

def geographic_item_id
  @geographic_item_id
end

#otu_idArray

Parameters:

  • otu_id (Array, Integer, String)

Returns:

  • (Array)


36
37
38
# File 'lib/queries/asserted_distribution/filter.rb', line 36

def otu_id
  @otu_id
end

#presenceBoolean?

Returns true - Return AssertedDistributions where the OTU is asserted as present according to the Source false - Return AssertedDistributions where the OTU is asserted as absent according to the Source nil - both.

Returns:

  • (Boolean, nil)

    true - Return AssertedDistributions where the OTU is asserted as present according to the Source false - Return AssertedDistributions where the OTU is asserted as absent according to the Source nil - both



61
62
63
# File 'lib/queries/asserted_distribution/filter.rb', line 61

def presence
  @presence
end

#radiusObject

Integer in Meters

!! defaults to 100m


75
76
77
# File 'lib/queries/asserted_distribution/filter.rb', line 75

def radius
  @radius
end

#taxon_name_idArray

Parameters:

  • all (taxon name ids, nil)

    Otus matching these taxon names

Returns:

  • (Array)


66
67
68
# File 'lib/queries/asserted_distribution/filter.rb', line 66

def taxon_name_id
  @taxon_name_id
end

#wktObject

Returns the value of attribute wkt.



53
54
55
# File 'lib/queries/asserted_distribution/filter.rb', line 53

def wkt
  @wkt
end

Instance Method Details

#and_clausesObject



271
272
273
274
275
276
# File 'lib/queries/asserted_distribution/filter.rb', line 271

def and_clauses
  [
    otu_id_facet,
    presence_facet,
  ]
end

#biological_association_query_facetObject



256
257
258
259
260
261
262
263
264
265
266
267
268
269
# File 'lib/queries/asserted_distribution/filter.rb', line 256

def biological_association_query_facet
  return nil if biological_association_query.nil?
  s = 'WITH query_ad_ba AS (' + biological_association_query.all.to_sql + ') '

  a = ::AssertedDistribution
    .joins("JOIN query_ad_ba as query_ad_ba1 on asserted_distributions.otu_id = query_ad_ba1.biological_association_subject_id AND query_ad_ba1.biological_association_subject_type = 'Otu'")

  b = ::AssertedDistribution
    .joins("JOIN query_ad_ba as query_ad_ba2 on asserted_distributions.otu_id = query_ad_ba2.biological_association_object_id AND query_ad_ba2.biological_association_object_type = 'Otu'")

  s << referenced_klass_union([a,b]).to_sql

  ::AssertedDistribution.from('(' + s + ') as asserted_distributions').distinct
end

#from_wkt(wkt_shape) ⇒ Object



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/queries/asserted_distribution/filter.rb', line 132

def from_wkt(wkt_shape)
  i = ::GeographicItem.joins(:geographic_areas).where(::GeographicItem.contained_by_wkt_sql(wkt_shape))

  j = ::GeographicArea.joins(:geographic_items).where(geographic_items: i)
  k = ::GeographicArea.descendants_of(j) # Add children that might not be caught because they don't have a shapes

  l = ::GeographicArea.from("((#{j.to_sql}) UNION (#{k.to_sql})) as geographic_areas").distinct

  s = 'WITH query_wkt_ad AS (' + l.all.to_sql + ') ' +
    ::AssertedDistribution
    .joins('JOIN query_wkt_ad as query_wkt_ad1 on query_wkt_ad1.id = asserted_distributions.geographic_area_id')
    .to_sql

  ::AssertedDistribution.from('(' + s + ') as asserted_distributions')
end

#geo_json_facetObject

Shape is a Hash in GeoJSON format



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/queries/asserted_distribution/filter.rb', line 149

def geo_json_facet
  return nil if geo_json.nil?
  if i = spatial_query

    # All spatial records
    j = ::GeographicArea.joins(:geographic_items).where(geographic_items: i)

    # Expand to include all descendants of any spatial match!
    # We only care about areas actually used here.
    k = ::GeographicArea.joins(:asserted_distributions).descendants_of(j)

    l = ::GeographicArea.from("((#{j.to_sql}) UNION (#{k.to_sql})) as geographic_areas").distinct

    return ::AssertedDistribution.where( geographic_area: l )
  else
    return nil
  end
end

#geographic_area_id_facetObject



184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/queries/asserted_distribution/filter.rb', line 184

def geographic_area_id_facet
  return nil if geographic_area_id.empty?

  a = nil

  case geographic_area_mode
  when nil, true # exact and spatial start the same
    a = ::GeographicArea.where(id: geographic_area_id)
  when false # descendants
    a = ::GeographicArea.descendants_of_any(geographic_area_id)
  end

  b = nil # from AssertedDistributions

  case geographic_area_mode
  when nil, false # exact, descendants
    b = ::AssertedDistribution.where(geographic_area: a)
  when true # spatial
    i = ::GeographicItem.joins(:geographic_areas).where(geographic_areas: a) # .unscope
    wkt_shape = ::GeographicItem.st_union(i).to_a.first['collection'].to_s # todo, check
    return from_wkt(wkt_shape)
  end

  b
end

#geographic_item_id_facetObject



215
216
217
218
219
220
# File 'lib/queries/asserted_distribution/filter.rb', line 215

def geographic_item_id_facet
  return nil if geographic_item_id.empty?
  ::GeographicArea.joins(:geographic_areas_geographic_items).where(
    geographic_areas_geographic_items: {geographic_item_id:}
  )
end

#merge_clausesObject



278
279
280
281
282
283
284
285
286
287
288
289
290
# File 'lib/queries/asserted_distribution/filter.rb', line 278

def merge_clauses
  [
    biological_association_query_facet,
    geo_json_facet,
    otu_query_facet,
    taxon_name_query_facet,

    geographic_area_id_facet,
    geographic_item_id_facet,
    taxon_name_id_facet,
    wkt_facet,
  ]
end

#otu_id_facetObject



210
211
212
213
# File 'lib/queries/asserted_distribution/filter.rb', line 210

def otu_id_facet
  return nil if otu_id.empty?
  table[:otu_id].in(otu_id)
end

#otu_query_facetObject



237
238
239
240
241
242
243
244
# File 'lib/queries/asserted_distribution/filter.rb', line 237

def otu_query_facet
  return nil if otu_query.nil?
  s = 'WITH query_otu_ad AS (' + otu_query.all.to_sql + ') ' +
    ::AssertedDistribution
    .joins('JOIN query_otu_ad as query_otu_ad1 on query_otu_ad1.id = asserted_distributions.otu_id')
    .to_sql
  ::AssertedDistribution.from('(' + s + ') as asserted_distributions')
end

#presence_facetObject



118
119
120
121
122
123
124
125
# File 'lib/queries/asserted_distribution/filter.rb', line 118

def presence_facet
  return nil if presence.nil?
  if presence
    table[:is_absent].eq_any(['f', nil]) # !! not eq_any()
  else
    table[:is_absent].eq('t')
  end
end

#spatial_queryGeographicItem scope

Returns:



169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/queries/asserted_distribution/filter.rb', line 169

def spatial_query
  if geometry = RGeo::GeoJSON.decode(geo_json)
    case geometry.geometry_type.to_s
    when 'Point'
      ::GeographicItem.joins(:geographic_areas).where( ::GeographicItem.within_radius_of_wkt_sql(geometry.to_s, radius ) )
    when 'Polygon', 'MultiPolygon'
      ::GeographicItem.joins(:geographic_areas).where(::GeographicItem.contained_by_wkt_sql(geometry.to_s))
    else
      nil
    end
  else
    nil
  end
end

#taxon_name_id_facetObject



222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/queries/asserted_distribution/filter.rb', line 222

def taxon_name_id_facet
  return nil if taxon_name_id.empty?
  if descendants
    h = Arel::Table.new(:taxon_name_hierarchies)
    o = Arel::Table.new(:otus)

    j = o.join(h, Arel::Nodes::InnerJoin).on(o[:taxon_name_id].eq(h[:descendant_id]))
    z = h[:ancestor_id].in(taxon_name_id)

    ::AssertedDistribution.joins(:otu).joins(j.join_sources).where(z)
  else
    ::AssertedDistribution.joins(:otu).where(otus: {taxon_name_id:})
  end
end

#taxon_name_query_facetObject



246
247
248
249
250
251
252
253
254
# File 'lib/queries/asserted_distribution/filter.rb', line 246

def taxon_name_query_facet
  return nil if taxon_name_query.nil?
  s = 'WITH query_tn_ad AS (' + taxon_name_query.all.to_sql + ') ' +
    ::AssertedDistribution
    .joins(:otu)
    .joins('JOIN query_tn_ad as query_tn_ad1 on query_tn_ad1.id = otus.taxon_name_id')
    .to_sql
  ::AssertedDistribution.from('(' + s + ') as asserted_distributions')
end

#wkt_facetObject



127
128
129
130
# File 'lib/queries/asserted_distribution/filter.rb', line 127

def wkt_facet
  return nil if wkt.nil?
  from_wkt(wkt)
end