# # PostGIS Adapter # # Common Spatial Adapter for ActiveRecord # # Code from # http://georuby.rubyforge.org Spatial Adapter # module SpatialAdapter #Translation of geometric data types def geometry_data_types { :point => { :name => "POINT" }, :line_string => { :name => "LINESTRING" }, :polygon => { :name => "POLYGON" }, :geometry_collection => { :name => "GEOMETRYCOLLECTION" }, :multi_point => { :name => "MULTIPOINT" }, :multi_line_string => { :name => "MULTILINESTRING" }, :multi_polygon => { :name => "MULTIPOLYGON" }, :geometry => { :name => "GEOMETRY"} } end end #using a mixin instead of subclassing Column since each adapter can have a specific subclass of Column module SpatialColumn attr_reader :geometry_type, :srid, :with_z, :with_m def initialize(name, default, sql_type = nil, null = true,srid=-1,with_z=false,with_m=false) super(name,default,sql_type,null) @geometry_type = geometry_simplified_type(@sql_type) @srid = srid @with_z = with_z @with_m = with_m end #Redefines type_cast to add support for geometries def type_cast(value) return nil if value.nil? case type when :geometry then self.class.string_to_geometry(value) else super end end #Redefines type_cast_code to add support for geometries. # #WARNING : Since ActiveRecord keeps only the string values directly returned from the database, it translates from these to the correct types everytime an attribute is read (using the code returned by this method), which is probably ok for simple types, but might be less than efficient for geometries. Also you cannot modify the geometry object returned directly or your change will not be saved. def type_cast_code(var_name) case type when :geometry then "#{self.class.name}.string_to_geometry(#{var_name})" else super end end #Redefines klass to add support for geometries def klass case type when :geometry then GeoRuby::SimpleFeatures::Geometry else super end end private #Redefines the simplified_type method to add behaviour for when a column is of type geometry def simplified_type(field_type) case field_type when /geometry|point|linestring|polygon|multipoint|multilinestring|multipolygon|geometrycollection/i then :geometry else super end end #less simlpified geometric type to be use in migrations def geometry_simplified_type(field_type) case field_type when /^point$/i then :point when /^linestring$/i then :line_string when /^polygon$/i then :polygon when /^geometry$/i then :geometry when /multipoint/i then :multi_point when /multilinestring/i then :multi_line_string when /multipolygon/i then :multi_polygon when /geometrycollection/i then :geometry_collection end end end