Class: CachedMap
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
Class Method Summary
collapse
Instance Method Summary
collapse
#errors_excepting, #full_error_messages_excepting, #identical, #is_community?, #is_in_use?, #similar
#annotates_community_object?, #associated_project_id_for_validation, #is_community?, #project_foreign_keys_are_in_same_project, #set_project_id
transaction_with_retry
Instance Attribute Details
#force_rebuild ⇒ Boolean?
15
16
17
|
# File 'app/models/cached_map.rb', line 15
def force_rebuild
@force_rebuild
end
|
#geo_json_string=(value) ⇒ Object
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.message.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.geography_as_geometry)
.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
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) 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
|
#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
|