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.
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.
13 14 15 |
# File 'app/models/cached_map.rb', line 13 def force_rebuild @force_rebuild end |
#geo_json_string=(value) ⇒ Object (writeonly)
10 11 12 |
# File 'app/models/cached_map.rb', line 10 def geo_json_string=(value) @geo_json_string = value end |
Class Method Details
.calculate_union(otu_scope, cached_map_type = 'CachedMapItem::WebLevel1') ⇒ Object
112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'app/models/cached_map.rb', line 112 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
80 81 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 |
# File 'app/models/cached_map.rb', line 80 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.
37 38 39 |
# File 'app/models/cached_map.rb', line 37 def cached_map_items CachedMapItem.where(type: cached_map_type, otu: otu_scope) end |
#cached_map_items_reference_total ⇒ Object
60 61 62 |
# File 'app/models/cached_map.rb', line 60 def cached_map_items_reference_total CachedMapItem.where(otu: otu_scope).sum(:reference_count) end |
#geo_json_to_s ⇒ Object
72 73 74 75 76 77 78 |
# File 'app/models/cached_map.rb', line 72 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
56 57 58 |
# File 'app/models/cached_map.rb', line 56 def latest_cached_map_item cached_map_items.order(:updated_at).first end |
#otu_scope ⇒ Object
64 65 66 67 68 69 70 |
# File 'app/models/cached_map.rb', line 64 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 syncronized through a change in a CachedMapItem we can trigger syncronizations that Update CachedMaps with callback hooks here, in theory.
28 29 30 31 32 |
# File 'app/models/cached_map.rb', line 28 def rebuild if !synced? self.geo_json_string = CachedMap.calculate_union(otu, cached_map_type: ) end end |
#synced? ⇒ Boolean
52 53 54 |
# File 'app/models/cached_map.rb', line 52 def synced? cached_map_items_reference_total == reference_count && latest_cached_map_item.created_at <= created_at end |