class RGeo::ActiveRecord::SpatialFactoryStore
Constants
- Entry
Attributes
registry[RW]
Public Class Methods
new()
click to toggle source
# File lib/rgeo/active_record/spatial_factory_store.rb, line 11 def initialize @registry = [] @default = nil end
Public Instance Methods
clear()
click to toggle source
# File lib/rgeo/active_record/spatial_factory_store.rb, line 32 def clear @registry = [] end
default(attrs = {})
click to toggle source
# File lib/rgeo/active_record/spatial_factory_store.rb, line 20 def default(attrs = {}) @default || default_for_attrs(attrs) end
default=(factory)
click to toggle source
# File lib/rgeo/active_record/spatial_factory_store.rb, line 24 def default=(factory) @default = factory end
factory(attrs)
click to toggle source
# File lib/rgeo/active_record/spatial_factory_store.rb, line 28 def factory(attrs) closest_factory(attrs) || default(attrs) end
register(factory, attrs = {})
click to toggle source
# File lib/rgeo/active_record/spatial_factory_store.rb, line 16 def register(factory, attrs = {}) registry.push(Entry.new(filter_attrs(attrs), factory)) end
Private Instance Methods
closest_factory(attrs)
click to toggle source
Match attrs to the closest equal to or less specific factory
That means that attrs can at most be matched to an Entry
with the same number of keys as it. But could match with a factory with only 1 key in its attrs.
Examples:
attrs = {sql_type: "geometry" }, entry_attrs = {sql_type: "geometry", geo_type: "point"} is not a match because the entry is more specific than attrs attrs = {sql_type: "geometry", geo_type: "point"}, entry_attrs = {sql_type: "geometry"} is a match because the entry is less specific than attrs and would be the fallback for all "geometry" types attrs = {sql_type: "geometry", geo_type: "point"}, entry_attrs = {sql_type: "geometry", geo_type: "linestring"} is not a match because there are mismatched keys
If there is no match, nil is returned
# File lib/rgeo/active_record/spatial_factory_store.rb, line 76 def closest_factory(attrs) max_matches = 0 registry.reduce(nil) do |selected_fac, entry| cmp = cmp_attrs(attrs, entry.attrs) if cmp > max_matches max_matches = cmp entry.factory else selected_fac end end end
cmp_attrs(attrs, oth)
click to toggle source
Returns number of common key/values or -1 if oth is bigger than attrs, or they have a mismatched key/value pair
# File lib/rgeo/active_record/spatial_factory_store.rb, line 92 def cmp_attrs(attrs, oth) return -1 if oth.size > attrs.size matches = 0 attrs.each do |k, v| next if oth[k].nil? return -1 unless v == oth[k] matches += 1 end matches end
default_for_attrs(attrs)
click to toggle source
# File lib/rgeo/active_record/spatial_factory_store.rb, line 38 def default_for_attrs(attrs) if attrs[:sql_type] =~ /geography/ Geographic.spherical_factory(to_factory_attrs(attrs)) else Cartesian.preferred_factory(to_factory_attrs(attrs)) end end
filter_attrs(attrs)
click to toggle source
# File lib/rgeo/active_record/spatial_factory_store.rb, line 54 def filter_attrs(attrs) attrs.slice(:geo_type, :has_m, :has_z, :sql_type, :srid) end
to_factory_attrs(attrs)
click to toggle source
# File lib/rgeo/active_record/spatial_factory_store.rb, line 46 def to_factory_attrs(attrs) { has_m_coordinate: attrs[:has_m], has_z_coordinate: attrs[:has_z], srid: (attrs[:srid] || 0), } end