Class: CachedMap
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- CachedMap
- Defined in:
- app/models/cached_map.rb
Overview
A CachedMap is a OTU specific map derived from AssertedDistribution and Georeference data via aggregation of the intermediate CachedMapItem level.
One OTU can have many CachedMaps if they are of different types.
Instance Attribute Summary collapse
-
#force_rebuild ⇒ Object
Boolean, nil.
- #geo_json_string ⇒ Object writeonly
Class Method Summary collapse
- .calculate_union(otu_scope, cached_map_type = 'CachedMapItem::WebLevel1') ⇒ Object
- .union_sql(otu_scope, cached_map_type = 'CachedMapItem::WebLevel1') ⇒ Object
Instance Method Summary collapse
-
#cached_map_items ⇒ Object
All cached_map items used to compose this cached_map.
- #cached_map_items_reference_total ⇒ Object
- #geo_json_to_s ⇒ Object
- #latest_cached_map_item ⇒ Object
- #otu_scope ⇒ Object
-
#rebuild ⇒ Object
TODO: Current production strategy is to present “out of date” when visualizing a CacheMap, then do complete rebuilds.
- #synced? ⇒ Boolean
Methods included from Shared::IsData
#errors_excepting, #full_error_messages_excepting, #identical, #is_community?, #is_destroyable?, #is_editable?, #is_in_use?, #is_in_users_projects?, #metamorphosize, #similar
Methods included from Housekeeping::Projects
#annotates_community_object?, #is_community?, #set_project_id
Methods inherited from ApplicationRecord
Instance Attribute Details
#force_rebuild ⇒ Object
Returns Boolean, nil.
15 16 17 |
# File 'app/models/cached_map.rb', line 15 def force_rebuild @force_rebuild end |
#geo_json_string=(value) ⇒ Object (writeonly)
12 13 14 |
# File 'app/models/cached_map.rb', line 12 def geo_json_string=(value) @geo_json_string = value end |
Class Method Details
.calculate_union(otu_scope, cached_map_type = 'CachedMapItem::WebLevel1') ⇒ Object
114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'app/models/cached_map.rb', line 114 def self.calculate_union(otu_scope, cached_map_type = 'CachedMapItem::WebLevel1') sql = union_sql(otu_scope, cached_map_type = 'CachedMapItem::WebLevel1') begin r = ActiveRecord::Base.connection.execute(sql) rescue ActiveRecord::StatementInvalid => e if e..include?('GEOSUnaryUnion') return nil else raise e end end r[0]['geojson'] end |
.union_sql(otu_scope, cached_map_type = 'CachedMapItem::WebLevel1') ⇒ Object
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'app/models/cached_map.rb', line 82 def self.union_sql(otu_scope, cached_map_type = 'CachedMapItem::WebLevel1') i = ::GeographicItem.select("#{GeographicItem::GEOMETRY_SQL.to_sql}") .joins('JOIN cached_map_items cmi on cmi.geographic_item_id = geographic_items.id') .joins('JOIN otu_scope AS otu_scope1 on otu_scope1.id = cmi.otu_id') .where('cmi.untranslated IS NULL OR cmi.untranslated <> true') .distinct s = "WITH otu_scope AS (#{otu_scope.to_sql}) " + i.to_sql # TODO: with untranslated handled we probable don't need Homogenize? # TODO: explore simplification optimization # - 0.01 drops the number of points by > 5x sql = "SELECT ST_AsGeoJSON( ST_SimplifyPreserveTopology( ST_CollectionHomogenize ( ST_CollectionExtract( ST_Union(geom_array) ) ), 0.01 ) ) AS geojson FROM ( SELECT ARRAY( #{s} ) AS geom_array ) AS subquery;" sql end |
Instance Method Details
#cached_map_items ⇒ Object
All cached_map items used to compose this cached_map.
39 40 41 |
# File 'app/models/cached_map.rb', line 39 def cached_map_items CachedMapItem.where(type: cached_map_type, otu: otu_scope) end |
#cached_map_items_reference_total ⇒ Object
62 63 64 |
# File 'app/models/cached_map.rb', line 62 def cached_map_items_reference_total CachedMapItem.where(otu: otu_scope).sum(:reference_count) end |
#geo_json_to_s ⇒ Object
74 75 76 77 78 79 80 |
# File 'app/models/cached_map.rb', line 74 def geo_json_to_s if respond_to?(:geo_json) # loaded as string in query geo_json else CachedMap.select('ST_AsGeoJSON(geometry) geo_json').find(id).geo_json end end |
#latest_cached_map_item ⇒ Object
58 59 60 |
# File 'app/models/cached_map.rb', line 58 def latest_cached_map_item cached_map_items.order(updated_at: :desc).first end |
#otu_scope ⇒ Object
66 67 68 69 70 71 72 |
# File 'app/models/cached_map.rb', line 66 def otu_scope if otu.taxon_name Otu.descendant_of_taxon_name(otu.taxon_name_id) else Otu.coordinate_otus(otu.id) end end |
#rebuild ⇒ Object
TODO: Current production strategy is to present “out of date” when visualizing a CacheMap, then do complete rebuilds.
This strategy can change when if/when we manage to get a comprehensive number of hooks into models such that state can be maintained.
Since all hooks are synchronized through a change in a CachedMapItem we can trigger syncronizations that Update CachedMaps with callback hooks here, in theory.
30 31 32 33 34 |
# File 'app/models/cached_map.rb', line 30 def rebuild if !synced? self.geo_json_string = CachedMap.calculate_union(otu, cached_map_type: ) end end |
#synced? ⇒ Boolean
54 55 56 |
# File 'app/models/cached_map.rb', line 54 def synced? cached_map_items_reference_total == reference_count && latest_cached_map_item.created_at <= created_at end |